xref: /csrg-svn/games/fortune/rnd.c (revision 30268)
1*30268Sbostic /*
2*30268Sbostic  * Copyright (c) 1986 Regents of the University of California.
3*30268Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*30268Sbostic  * specifies the terms and conditions for redistribution.
5*30268Sbostic  */
6*30268Sbostic 
7*30268Sbostic #ifndef lint
8*30268Sbostic static char sccsid[] = "@(#)rnd.c	5.1 (Berkeley) 12/09/86";
9*30268Sbostic #endif not lint
10*30268Sbostic 
11*30268Sbostic /*
12*30268Sbostic  * code for when the good (berkeley) random number generator is around
13*30268Sbostic  */
14*30268Sbostic 
15*30268Sbostic rnd(num)
16*30268Sbostic {
17*30268Sbostic 	return (random() % num);
18*30268Sbostic }
19*30268Sbostic 
20*30268Sbostic srnd(num)
21*30268Sbostic {
22*30268Sbostic 	srandom(num);
23*30268Sbostic }
24*30268Sbostic 
25*30268Sbostic #ifdef	NO_RANDOM
26*30268Sbostic 
27*30268Sbostic #ifndef lint
28*30268Sbostic static char sccsid[] = "@(#)random.c	4.2	(Berkeley)	83/01/02";
29*30268Sbostic #endif
30*30268Sbostic 
31*30268Sbostic #include	<stdio.h>
32*30268Sbostic 
33*30268Sbostic /*
34*30268Sbostic  * random.c:
35*30268Sbostic  * An improved random number generation package.  In addition to the standard
36*30268Sbostic  * rand()/srand() like interface, this package also has a special state info
37*30268Sbostic  * interface.  The initstate() routine is called with a seed, an array of
38*30268Sbostic  * bytes, and a count of how many bytes are being passed in; this array is then
39*30268Sbostic  * initialized to contain information for random number generation with that
40*30268Sbostic  * much state information.  Good sizes for the amount of state information are
41*30268Sbostic  * 32, 64, 128, and 256 bytes.  The state can be switched by calling the
42*30268Sbostic  * setstate() routine with the same array as was initiallized with initstate().
43*30268Sbostic  * By default, the package runs with 128 bytes of state information and
44*30268Sbostic  * generates far better random numbers than a linear congruential generator.
45*30268Sbostic  * If the amount of state information is less than 32 bytes, a simple linear
46*30268Sbostic  * congruential R.N.G. is used.
47*30268Sbostic  * Internally, the state information is treated as an array of longs; the
48*30268Sbostic  * zeroeth element of the array is the type of R.N.G. being used (small
49*30268Sbostic  * integer); the remainder of the array is the state information for the
50*30268Sbostic  * R.N.G.  Thus, 32 bytes of state information will give 7 longs worth of
51*30268Sbostic  * state information, which will allow a degree seven polynomial.  (Note: the
52*30268Sbostic  * zeroeth word of state information also has some other information stored
53*30268Sbostic  * in it -- see setstate() for details).
54*30268Sbostic  * The random number generation technique is a linear feedback shift register
55*30268Sbostic  * approach, employing trinomials (since there are fewer terms to sum up that
56*30268Sbostic  * way).  In this approach, the least significant bit of all the numbers in
57*30268Sbostic  * the state table will act as a linear feedback shift register, and will have
58*30268Sbostic  * period 2^deg - 1 (where deg is the degree of the polynomial being used,
59*30268Sbostic  * assuming that the polynomial is irreducible and primitive).  The higher
60*30268Sbostic  * order bits will have longer periods, since their values are also influenced
61*30268Sbostic  * by pseudo-random carries out of the lower bits.  The total period of the
62*30268Sbostic  * generator is approximately deg*(2**deg - 1); thus doubling the amount of
63*30268Sbostic  * state information has a vast influence on the period of the generator.
64*30268Sbostic  * Note: the deg*(2**deg - 1) is an approximation only good for large deg,
65*30268Sbostic  * when the period of the shift register is the dominant factor.  With deg
66*30268Sbostic  * equal to seven, the period is actually much longer than the 7*(2**7 - 1)
67*30268Sbostic  * predicted by this formula.
68*30268Sbostic  */
69*30268Sbostic 
70*30268Sbostic 
71*30268Sbostic 
72*30268Sbostic /*
73*30268Sbostic  * For each of the currently supported random number generators, we have a
74*30268Sbostic  * break value on the amount of state information (you need at least this
75*30268Sbostic  * many bytes of state info to support this random number generator), a degree
76*30268Sbostic  * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
77*30268Sbostic  * the separation between the two lower order coefficients of the trinomial.
78*30268Sbostic  */
79*30268Sbostic 
80*30268Sbostic #define		TYPE_0		0		/* linear congruential */
81*30268Sbostic #define		BREAK_0		8
82*30268Sbostic #define		DEG_0		0
83*30268Sbostic #define		SEP_0		0
84*30268Sbostic 
85*30268Sbostic #define		TYPE_1		1		/* x**7 + x**3 + 1 */
86*30268Sbostic #define		BREAK_1		32
87*30268Sbostic #define		DEG_1		7
88*30268Sbostic #define		SEP_1		3
89*30268Sbostic 
90*30268Sbostic #define		TYPE_2		2		/* x**15 + x + 1 */
91*30268Sbostic #define		BREAK_2		64
92*30268Sbostic #define		DEG_2		15
93*30268Sbostic #define		SEP_2		1
94*30268Sbostic 
95*30268Sbostic #define		TYPE_3		3		/* x**31 + x**3 + 1 */
96*30268Sbostic #define		BREAK_3		128
97*30268Sbostic #define		DEG_3		31
98*30268Sbostic #define		SEP_3		3
99*30268Sbostic 
100*30268Sbostic #define		TYPE_4		4		/* x**63 + x + 1 */
101*30268Sbostic #define		BREAK_4		256
102*30268Sbostic #define		DEG_4		63
103*30268Sbostic #define		SEP_4		1
104*30268Sbostic 
105*30268Sbostic 
106*30268Sbostic /*
107*30268Sbostic  * Array versions of the above information to make code run faster -- relies
108*30268Sbostic  * on fact that TYPE_i == i.
109*30268Sbostic  */
110*30268Sbostic 
111*30268Sbostic #define		MAX_TYPES	5		/* max number of types above */
112*30268Sbostic 
113*30268Sbostic static  int		degrees[ MAX_TYPES ]	= { DEG_0, DEG_1, DEG_2,
114*30268Sbostic 								DEG_3, DEG_4 };
115*30268Sbostic 
116*30268Sbostic static  int		seps[ MAX_TYPES ]	= { SEP_0, SEP_1, SEP_2,
117*30268Sbostic 								SEP_3, SEP_4 };
118*30268Sbostic 
119*30268Sbostic 
120*30268Sbostic 
121*30268Sbostic /*
122*30268Sbostic  * Initially, everything is set up as if from :
123*30268Sbostic  *		initstate( 1, &randtbl, 128 );
124*30268Sbostic  * Note that this initialization takes advantage of the fact that srandom()
125*30268Sbostic  * advances the front and rear pointers 10*rand_deg times, and hence the
126*30268Sbostic  * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
127*30268Sbostic  * element of the state information, which contains info about the current
128*30268Sbostic  * position of the rear pointer is just
129*30268Sbostic  *	MAX_TYPES*(rptr - state) + TYPE_3 == TYPE_3.
130*30268Sbostic  */
131*30268Sbostic 
132*30268Sbostic static  long		randtbl[ DEG_3 + 1 ]	= { TYPE_3,
133*30268Sbostic 			    0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342,
134*30268Sbostic 			    0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb,
135*30268Sbostic 			    0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
136*30268Sbostic 			    0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86,
137*30268Sbostic 			    0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7,
138*30268Sbostic 			    0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
139*30268Sbostic 			    0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b,
140*30268Sbostic 					0xf5ad9d0e, 0x8999220b, 0x27fb47b9 };
141*30268Sbostic 
142*30268Sbostic /*
143*30268Sbostic  * fptr and rptr are two pointers into the state info, a front and a rear
144*30268Sbostic  * pointer.  These two pointers are always rand_sep places aparts, as they cycle
145*30268Sbostic  * cyclically through the state information.  (Yes, this does mean we could get
146*30268Sbostic  * away with just one pointer, but the code for random() is more efficient this
147*30268Sbostic  * way).  The pointers are left positioned as they would be from the call
148*30268Sbostic  *			initstate( 1, randtbl, 128 )
149*30268Sbostic  * (The position of the rear pointer, rptr, is really 0 (as explained above
150*30268Sbostic  * in the initialization of randtbl) because the state table pointer is set
151*30268Sbostic  * to point to randtbl[1] (as explained below).
152*30268Sbostic  */
153*30268Sbostic 
154*30268Sbostic static  long		*fptr			= &randtbl[ SEP_3 + 1 ];
155*30268Sbostic static  long		*rptr			= &randtbl[ 1 ];
156*30268Sbostic 
157*30268Sbostic 
158*30268Sbostic 
159*30268Sbostic /*
160*30268Sbostic  * The following things are the pointer to the state information table,
161*30268Sbostic  * the type of the current generator, the degree of the current polynomial
162*30268Sbostic  * being used, and the separation between the two pointers.
163*30268Sbostic  * Note that for efficiency of random(), we remember the first location of
164*30268Sbostic  * the state information, not the zeroeth.  Hence it is valid to access
165*30268Sbostic  * state[-1], which is used to store the type of the R.N.G.
166*30268Sbostic  * Also, we remember the last location, since this is more efficient than
167*30268Sbostic  * indexing every time to find the address of the last element to see if
168*30268Sbostic  * the front and rear pointers have wrapped.
169*30268Sbostic  */
170*30268Sbostic 
171*30268Sbostic static  long		*state			= &randtbl[ 1 ];
172*30268Sbostic 
173*30268Sbostic static  int		rand_type		= TYPE_3;
174*30268Sbostic static  int		rand_deg		= DEG_3;
175*30268Sbostic static  int		rand_sep		= SEP_3;
176*30268Sbostic 
177*30268Sbostic static  long		*end_ptr		= &randtbl[ DEG_3 + 1 ];
178*30268Sbostic 
179*30268Sbostic 
180*30268Sbostic 
181*30268Sbostic /*
182*30268Sbostic  * srandom:
183*30268Sbostic  * Initialize the random number generator based on the given seed.  If the
184*30268Sbostic  * type is the trivial no-state-information type, just remember the seed.
185*30268Sbostic  * Otherwise, initializes state[] based on the given "seed" via a linear
186*30268Sbostic  * congruential generator.  Then, the pointers are set to known locations
187*30268Sbostic  * that are exactly rand_sep places apart.  Lastly, it cycles the state
188*30268Sbostic  * information a given number of times to get rid of any initial dependencies
189*30268Sbostic  * introduced by the L.C.R.N.G.
190*30268Sbostic  * Note that the initialization of randtbl[] for default usage relies on
191*30268Sbostic  * values produced by this routine.
192*30268Sbostic  */
193*30268Sbostic 
194*30268Sbostic srandom( x )
195*30268Sbostic 
196*30268Sbostic     unsigned		x;
197*30268Sbostic {
198*30268Sbostic     	register  int		i, j;
199*30268Sbostic 
200*30268Sbostic 	if(  rand_type  ==  TYPE_0  )  {
201*30268Sbostic 	    state[ 0 ] = x;
202*30268Sbostic 	}
203*30268Sbostic 	else  {
204*30268Sbostic 	    j = 1;
205*30268Sbostic 	    state[ 0 ] = x;
206*30268Sbostic 	    for( i = 1; i < rand_deg; i++ )  {
207*30268Sbostic 		state[i] = 1103515245*state[i - 1] + 12345;
208*30268Sbostic 	    }
209*30268Sbostic 	    fptr = &state[ rand_sep ];
210*30268Sbostic 	    rptr = &state[ 0 ];
211*30268Sbostic 	    for( i = 0; i < 10*rand_deg; i++ )  random();
212*30268Sbostic 	}
213*30268Sbostic }
214*30268Sbostic 
215*30268Sbostic 
216*30268Sbostic 
217*30268Sbostic /*
218*30268Sbostic  * initstate:
219*30268Sbostic  * Initialize the state information in the given array of n bytes for
220*30268Sbostic  * future random number generation.  Based on the number of bytes we
221*30268Sbostic  * are given, and the break values for the different R.N.G.'s, we choose
222*30268Sbostic  * the best (largest) one we can and set things up for it.  srandom() is
223*30268Sbostic  * then called to initialize the state information.
224*30268Sbostic  * Note that on return from srandom(), we set state[-1] to be the type
225*30268Sbostic  * multiplexed with the current value of the rear pointer; this is so
226*30268Sbostic  * successive calls to initstate() won't lose this information and will
227*30268Sbostic  * be able to restart with setstate().
228*30268Sbostic  * Note: the first thing we do is save the current state, if any, just like
229*30268Sbostic  * setstate() so that it doesn't matter when initstate is called.
230*30268Sbostic  * Returns a pointer to the old state.
231*30268Sbostic  */
232*30268Sbostic 
233*30268Sbostic char  *
234*30268Sbostic initstate( seed, arg_state, n )
235*30268Sbostic 
236*30268Sbostic     unsigned		seed;			/* seed for R. N. G. */
237*30268Sbostic     char		*arg_state;		/* pointer to state array */
238*30268Sbostic     int			n;			/* # bytes of state info */
239*30268Sbostic {
240*30268Sbostic 	register  char		*ostate		= (char *)( &state[ -1 ] );
241*30268Sbostic 
242*30268Sbostic 	if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
243*30268Sbostic 	else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
244*30268Sbostic 	if(  n  <  BREAK_1  )  {
245*30268Sbostic 	    if(  n  <  BREAK_0  )  {
246*30268Sbostic 		fprintf( stderr, "initstate: not enough state (%d bytes) with which to do jack; ignored.\n" );
247*30268Sbostic 		return;
248*30268Sbostic 	    }
249*30268Sbostic 	    rand_type = TYPE_0;
250*30268Sbostic 	    rand_deg = DEG_0;
251*30268Sbostic 	    rand_sep = SEP_0;
252*30268Sbostic 	}
253*30268Sbostic 	else  {
254*30268Sbostic 	    if(  n  <  BREAK_2  )  {
255*30268Sbostic 		rand_type = TYPE_1;
256*30268Sbostic 		rand_deg = DEG_1;
257*30268Sbostic 		rand_sep = SEP_1;
258*30268Sbostic 	    }
259*30268Sbostic 	    else  {
260*30268Sbostic 		if(  n  <  BREAK_3  )  {
261*30268Sbostic 		    rand_type = TYPE_2;
262*30268Sbostic 		    rand_deg = DEG_2;
263*30268Sbostic 		    rand_sep = SEP_2;
264*30268Sbostic 		}
265*30268Sbostic 		else  {
266*30268Sbostic 		    if(  n  <  BREAK_4  )  {
267*30268Sbostic 			rand_type = TYPE_3;
268*30268Sbostic 			rand_deg = DEG_3;
269*30268Sbostic 			rand_sep = SEP_3;
270*30268Sbostic 		    }
271*30268Sbostic 		    else  {
272*30268Sbostic 			rand_type = TYPE_4;
273*30268Sbostic 			rand_deg = DEG_4;
274*30268Sbostic 			rand_sep = SEP_4;
275*30268Sbostic 		    }
276*30268Sbostic 		}
277*30268Sbostic 	    }
278*30268Sbostic 	}
279*30268Sbostic 	state = &(  ( (long *)arg_state )[1]  );	/* first location */
280*30268Sbostic 	end_ptr = &state[ rand_deg ];	/* must set end_ptr before srandom */
281*30268Sbostic 	srandom( seed );
282*30268Sbostic 	if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
283*30268Sbostic 	else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
284*30268Sbostic 	return( ostate );
285*30268Sbostic }
286*30268Sbostic 
287*30268Sbostic 
288*30268Sbostic 
289*30268Sbostic /*
290*30268Sbostic  * setstate:
291*30268Sbostic  * Restore the state from the given state array.
292*30268Sbostic  * Note: it is important that we also remember the locations of the pointers
293*30268Sbostic  * in the current state information, and restore the locations of the pointers
294*30268Sbostic  * from the old state information.  This is done by multiplexing the pointer
295*30268Sbostic  * location into the zeroeth word of the state information.
296*30268Sbostic  * Note that due to the order in which things are done, it is OK to call
297*30268Sbostic  * setstate() with the same state as the current state.
298*30268Sbostic  * Returns a pointer to the old state information.
299*30268Sbostic  */
300*30268Sbostic 
301*30268Sbostic char  *
302*30268Sbostic setstate( arg_state )
303*30268Sbostic 
304*30268Sbostic     char		*arg_state;
305*30268Sbostic {
306*30268Sbostic 	register  long		*new_state	= (long *)arg_state;
307*30268Sbostic 	register  int		type		= new_state[0]%MAX_TYPES;
308*30268Sbostic 	register  int		rear		= new_state[0]/MAX_TYPES;
309*30268Sbostic 	char			*ostate		= (char *)( &state[ -1 ] );
310*30268Sbostic 
311*30268Sbostic 	if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
312*30268Sbostic 	else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
313*30268Sbostic 	switch(  type  )  {
314*30268Sbostic 	    case  TYPE_0:
315*30268Sbostic 	    case  TYPE_1:
316*30268Sbostic 	    case  TYPE_2:
317*30268Sbostic 	    case  TYPE_3:
318*30268Sbostic 	    case  TYPE_4:
319*30268Sbostic 		rand_type = type;
320*30268Sbostic 		rand_deg = degrees[ type ];
321*30268Sbostic 		rand_sep = seps[ type ];
322*30268Sbostic 		break;
323*30268Sbostic 
324*30268Sbostic 	    default:
325*30268Sbostic 		fprintf( stderr, "setstate: state info has been munged; not changed.\n" );
326*30268Sbostic 	}
327*30268Sbostic 	state = &new_state[ 1 ];
328*30268Sbostic 	if(  rand_type  !=  TYPE_0  )  {
329*30268Sbostic 	    rptr = &state[ rear ];
330*30268Sbostic 	    fptr = &state[ (rear + rand_sep)%rand_deg ];
331*30268Sbostic 	}
332*30268Sbostic 	end_ptr = &state[ rand_deg ];		/* set end_ptr too */
333*30268Sbostic 	return( ostate );
334*30268Sbostic }
335*30268Sbostic 
336*30268Sbostic 
337*30268Sbostic 
338*30268Sbostic /*
339*30268Sbostic  * random:
340*30268Sbostic  * If we are using the trivial TYPE_0 R.N.G., just do the old linear
341*30268Sbostic  * congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
342*30268Sbostic  * same in all ther other cases due to all the global variables that have been
343*30268Sbostic  * set up.  The basic operation is to add the number at the rear pointer into
344*30268Sbostic  * the one at the front pointer.  Then both pointers are advanced to the next
345*30268Sbostic  * location cyclically in the table.  The value returned is the sum generated,
346*30268Sbostic  * reduced to 31 bits by throwing away the "least random" low bit.
347*30268Sbostic  * Note: the code takes advantage of the fact that both the front and
348*30268Sbostic  * rear pointers can't wrap on the same call by not testing the rear
349*30268Sbostic  * pointer if the front one has wrapped.
350*30268Sbostic  * Returns a 31-bit random number.
351*30268Sbostic  */
352*30268Sbostic 
353*30268Sbostic long
354*30268Sbostic random()
355*30268Sbostic {
356*30268Sbostic 	long		i;
357*30268Sbostic 
358*30268Sbostic 	if(  rand_type  ==  TYPE_0  )  {
359*30268Sbostic 	    i = state[0] = ( state[0]*1103515245 + 12345 )&0x7fffffff;
360*30268Sbostic 	}
361*30268Sbostic 	else  {
362*30268Sbostic 	    *fptr += *rptr;
363*30268Sbostic 	    i = (*fptr >> 1)&0x7fffffff;	/* chucking least random bit */
364*30268Sbostic 	    if(  ++fptr  >=  end_ptr  )  {
365*30268Sbostic 		fptr = state;
366*30268Sbostic 		++rptr;
367*30268Sbostic 	    }
368*30268Sbostic 	    else  {
369*30268Sbostic 		if(  ++rptr  >=  end_ptr  )  rptr = state;
370*30268Sbostic 	    }
371*30268Sbostic 	}
372*30268Sbostic 	return( i );
373*30268Sbostic }
374*30268Sbostic 
375*30268Sbostic #endif	NO_RANDOM
376