/*
	Random number generator

	Modelled after "Algorithm A" in
	Knuth, D. E. (1981). The art of computer programming, volume 2, page 27.

	7/26/90 WRG
*/
#include <ncbi.h>
#include <gishlib.h>

static long	state[33] = {
	0xd53f1852,  0xdfc78b83,  0x4f256096,  0xe643df7,
	0x82c359bf,  0xc7794dfa,  0xd5e9ffaa,  0x2c8cb64a,
	0x2f07b334,  0xad5a7eb5,  0x96dc0cde,  0x6fc24589,
	0xa5853646,  0xe71576e2,  0xdae30df,  0xb09ce711,
	0x5e56ef87,  0x4b4b0082,  0x6f4f340e,  0xc5bb17e8,
	0xd788d765,  0x67498087,  0x9d7aba26,  0x261351d4,
	0x411ee7ea,  0x393a263,  0x2c5a5835,  0xc115fcd8,
	0x25e9132c,  0xd0c6e906,  0xc2bc5b2d,  0x6c065c98,
	0x6e37bd55 };
	/*0x4916e478,  0xeeff646c,  0x4a12cbb3,
	0x762766b0,  0xc04ed22,  0x4532830c,  0x6a39a598,
	0xd52eedea,  0x30944602,  0x9edcd019,  0xa1ff73c5,
	0x4752d571,  0x3aa3871e,  0xbd5d31f,  0xdfcef161,
	0xa204bf2f,  0xa86b7e27,  0x6ca3bfa8,  0x2873a095,
	0xacfc6639,  0xc4882d1e,  0x6690ccae  };
	*/

#define r_off	12

static long	PNTR rJ = &state[r_off],
			PNTR rK = &state[DIM(state)-1];

void _cdecl
rnd_seed(x)
	long	x;
{
	register int	i;

	state[0] = x;
	for (i=1; i<DIM(state); ++i) {
		state[i] = 1103515245*state[i-1] + 12345;
	}

	rJ = &state[r_off];
	rK = &state[DIM(state)-1];

	for (i=0; i<10*DIM(state); ++i)
		(void) rnd_gen();
}


/*
	rnd_gen --  return value in the range 0 <= x <= 2**31 - 1
*/
long _cdecl
rnd_gen()
{
	register long	r;

	r = *rK;
	r += *rJ--;
	*rK-- = r&0xffffffff;

	if (rK < state)
		rK = &state[DIM(state)-1];
	else
		if (rJ < state)
			rJ = &state[DIM(state)-1];
	return (r>>1)&0x7fffffff; /* discard the least-random bit */
}
