16. Random Number Generation

Gest implements an internal PRNG using a simple LCG, similar to many implementations of rand(). This is done to make Gest more consistent across platforms.

It is (perhaps erroneously) assumed that long integer values are at least 32-bits long.

<<gest_d>>=
unsigned long rng;

The initial RNG state can be seeded with gest_seed.

<<funcdefs>>=
void gest_seed(gest_d *g, unsigned long rng);
<<funcs>>=
void gest_seed(gest_d *g, unsigned long rng)
{
    g->rng = rng;
}

At initializatin, it is seeded with the system randfunction. For more consistent results, gest_seed can be explicit called immediately after initialization.

<<init>>=
gest_seed(g, rand());

A random value is produced with gest_rand.

<<funcdefs>>=
unsigned long gest_rand(gest_d *g);
<<funcs>>=
unsigned long gest_rand(gest_d *g)
{
    g->rng = (1103515245 * g->rng + 12345) % 2147483648;
    return g->rng;
}

A normalized floating point value can be returned with gest_randf.

<<funcdefs>>=
SKFLT gest_randf(gest_d *g);
<<funcs>>=
SKFLT gest_randf(gest_d *g)
{
    unsigned long x;

    x = gest_rand(g);

    return (SKFLT)x / 2147483648.0;
}

A random integer between 0 and N-1 can be found with gest_randi.

<<funcdefs>>=
int gest_randi(gest_d *g, int N);
<<funcs>>=
int gest_randi(gest_d *g, int N)
{
    int x;

    x = floor(gest_randf(g) * N);

    if (x >= N) x = N - 1;

    return x;
}



prev | home | next