ms@ccieng5.UUCP (Mark L. Stevans) (10/12/83)
To the poster who requested a random number generator in C: The following code implements and demonstrates a random number generator I designed for games. It is based on an old IBM paper on random number generators. It should generate pseudorandom doubles with a cycle length of about 2**30, more than enough for most applications. This is intended for use on processors with at least 32 bits of precision for longs and doubles, like a VAX. To use this generator, call inirandom(i) where i is an ODD unsigned int and (1 < i < 2**15). Then x = random() will return a random double x where (0. <= x < 1.). If you wish to test it out, try something like 'a.out | fgrep .4843' and watch how few lines match, and how they're all different. /* THE BEGINNING OF THE RANDOM NUMBER STUFF */ #define THIRTYBITS 0x3fffffff unsigned long rx, ru; long odd(i) /* Yes, I should have used a define here. */ long i; { return ((i % 2) == 1); } /* ** inirandom starts the random number generator at a point determined by ** its positive unsigned long argument i. */ inirandom(i) long i; { if ((i <= 0) || (!odd(i))) { printf("Inirandom: argument must be an odd positive long\n"); return (1); } ru = (unsigned) i; /* ** This next line is the heart of the whole thing, so don't try ** changing these constants! */ rx = (unsigned) ((2 << 15) + 3); /* rx = 2 ** 15 + 3 */ return (0); } /* ** random returns a randomly distributed double between 0 and 1. */ double random() { ru *= rx; ru &= (unsigned) THIRTYBITS; /* Take a 30 bit modulus */ return (((double) ru) / (THIRTYBITS + 1)); } main() { /* ** Calling inirandom with a different positive long argument ** will make random start at a different number in the random ** double sequence. */ inirandom(1); for (;;) printf("%f10\n", random()); } /* THE END OF THE RANDOM NUMBER STUFF */