OSDN Git Service

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