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