/* * random: * * If we are using the trivial TYPE_0 R.N.G., just do the old linear * congruential bit. Otherwise, we do our fancy trinomial stuff, which is * the same in all the other cases due to all the global variables that have * been set up. The basic operation is to add the number at the rear pointer * into the one at the front pointer. Then both pointers are advanced to * the next location cyclically in the table. The value returned is the sum * generated, reduced to 31 bits by throwing away the "least random" low bit. * * Note: the code takes advantage of the fact that both the front and * rear pointers can't wrap on the same call by not testing the rear * pointer if the front one has wrapped. * * Returns a 31-bit random number. */ long random(void) { uint32_t i; uint32_t *f, *r; if (rand_type == TYPE_0) { i = state[0]; state[0] = i = good_rand(i); } else { /* * Use local variables rather than static variables for speed. */ f = fptr; r = rptr; *f += *r; i = *f >> 1; /* chucking least random bit */ if (++f >= end_ptr) { f = state; ++r; } else if (++r >= end_ptr) { r = state; } fptr = f; rptr = r; } return ((long)i); }
void VRND_SeedTestable(unsigned int x) { int i, lim; state[0] = (uint32_t)x; for (i = 1; i < rand_deg; i++) state[i] = good_rand(state[i - 1]); fptr = &state[rand_sep]; rptr = &state[0]; lim = 10 * rand_deg; for (i = 0; i < lim; i++) (void)VRND_RandomTestable(); }
/* * srandom: * * Initialize the random number generator based on the given seed. If the * type is the trivial no-state-information type, just remember the seed. * Otherwise, initializes state[] based on the given "seed" via a linear * congruential generator. Then, the pointers are set to known locations * that are exactly rand_sep places apart. Lastly, it cycles the state * information a given number of times to get rid of any initial dependencies * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] * for default usage relies on values produced by this routine. */ void srandom(unsigned int x) { int i, lim; state[0] = (uint32_t)x; if (rand_type == TYPE_0) lim = NSHUFF; else { for (i = 1; i < rand_deg; i++) state[i] = good_rand(state[i - 1]); fptr = &state[rand_sep]; rptr = &state[0]; lim = 10 * rand_deg; } for (i = 0; i < lim; i++) (void)random(); }