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