YARNG -- Yet Another Random Number Generator
Mark L. Stevans
ms at ccieng5.UUCP
Wed Oct 12 07:31:57 AEST 1983
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 */
More information about the Comp.lang.c
mailing list