Bug fix for 4.2bsd random.c

D. Mitchell don at allegra.UUCP
Thu Apr 19 09:56:54 AEST 1984


1,348c
/*
 *	Additive Random Number Generator  (see: Knuth 3.2.2)
 *	D. P. Mitchell  84/04/16.
 */
#define LENGTH	97
#define TAP	12
#define MANTISSA 56

static long    y[LENGTH],  *tap =  &y[0],  *feedback =  &y[LENGTH - TAP];
static double fy[LENGTH], *ftap = &fy[0], *ffeedback = &fy[LENGTH - TAP];
static unsigned long x = 0xc0393e8d;

random()
{
	if (--tap < y) {
		if (x)		/* effect of srandom might be delayed */
			setup();
		tap += LENGTH;
	}
	if (--feedback < y)
		feedback += LENGTH;
	return (*feedback += *tap) >> 1 & 0x7fffffff;
}

double
frandom()
{
	double sum;

	if (--ftap < fy) {
		if (x)		/* fy cannot be preset portably! */
			setup();
		ftap += LENGTH;
	}
	if (--ffeedback < fy)
		ffeedback += LENGTH;
	sum = *ftap + *ffeedback;
	if (sum >= 1.0) {
		sum = *ftap - 0.5;	/* must not overflow! */
		sum += *ffeedback - 0.5;
	}
	*ffeedback = sum;
	return sum;
}

srandom(seed)
long seed;
{
	x = seed;
}

static
setup()
{
	long mask;
	double divisor;
	int i;

	for (i = 0; i < LENGTH; i++) {
		x = 177988*x*x + 505360173*x + 907633385;
		y[i]  = x;
	}
	mask = 0x7fffffff >> (63 - MANTISSA);
	divisor = (double)mask + 1.0;
	for (i = 0; i < LENGTH; i++) {
		x = 177988*x*x + 505360173*x + 907633385;
		fy[i] = (double)x / 4294967296.0;
		x = 177988*x*x + 505360173*x + 907633385;
		fy[i] = ((double)(x & mask) + fy[i]) / divisor;
	}
	x = 0;
}
.



More information about the Comp.unix.wizards mailing list