SVN_SILENT made messages (.desktop file)
[kdeartwork.git] / kscreensaver / kdesavers / vm_random.c
blobea0cd96a6e4288520c152b40710d600d39262805
1 /*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
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.
19 * Please note that as of July 22, 1999, the licensees and distributors
20 * are no longer required to include the above mentioned acknowledgement
21 * within advertising materials. For full details see
22 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
26 * This is derived from the Berkeley source:
27 * @(#)random.c 5.5 (Berkeley) 7/6/88
28 * It was reworked for the GNU C Library by Roland McGrath.
29 * Rewritten to be reentrant by Ulrich Drepper, 1995
32 #include <limits.h>
33 #include <stdlib.h>
34 #include "vm_random.h"
36 /* An improved random number generation package. In addition to the standard
37 rand()/srand() like interface, this package also has a special state info
38 interface. The initstate() routine is called with a seed, an array of
39 bytes, and a count of how many bytes are being passed in; this array is
40 then initialized to contain information for random number generation with
41 that much state information. Good sizes for the amount of state
42 information are 32, 64, 128, and 256 bytes. The state can be switched by
43 calling the setstate() function with the same array as was initialized
44 with initstate(). By default, the package runs with 128 bytes of state
45 information and generates far better random numbers than a linear
46 congruential generator. If the amount of state information is less than
47 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
48 state information is treated as an array of longs; the zeroth element of
49 the array is the type of R.N.G. being used (small integer); the remainder
50 of the array is the state information for the R.N.G. Thus, 32 bytes of
51 state information will give 7 longs worth of state information, which will
52 allow a degree seven polynomial. (Note: The zeroth word of state
53 information also has some other information stored in it; see setstate
54 for details). The random number generation technique is a linear feedback
55 shift register approach, employing trinomials (since there are fewer terms
56 to sum up that way). In this approach, the least significant bit of all
57 the numbers in the state table will act as a linear feedback shift register,
58 and will have period 2^deg - 1 (where deg is the degree of the polynomial
59 being used, assuming that the polynomial is irreducible and primitive).
60 The higher order bits will have longer periods, since their values are
61 also influenced by pseudo-random carries out of the lower bits. The
62 total period of the generator is approximately deg*(2**deg - 1); thus
63 doubling the amount of state information has a vast influence on the
64 period of the generator. Note: The deg*(2**deg - 1) is an approximation
65 only good for large deg, when the period of the shift register is the
66 dominant factor. With deg equal to seven, the period is actually much
67 longer than the 7*(2**7 - 1) predicted by this formula. */
71 /* For each of the currently supported random number generators, we have a
72 break value on the amount of state information (you need at least this many
73 bytes of state info to support this random number generator), a degree for
74 the polynomial (actually a trinomial) that the R.N.G. is based on, and
75 separation between the two lower order coefficients of the trinomial. */
77 /* Linear congruential. */
78 #define TYPE_0 0
79 #define BREAK_0 8
80 #define DEG_0 0
81 #define SEP_0 0
83 /* x**7 + x**3 + 1. */
84 #define TYPE_1 1
85 #define BREAK_1 32
86 #define DEG_1 7
87 #define SEP_1 3
89 /* x**15 + x + 1. */
90 #define TYPE_2 2
91 #define BREAK_2 64
92 #define DEG_2 15
93 #define SEP_2 1
95 /* x**31 + x**3 + 1. */
96 #define TYPE_3 3
97 #define BREAK_3 128
98 #define DEG_3 31
99 #define SEP_3 3
101 /* x**63 + x + 1. */
102 #define TYPE_4 4
103 #define BREAK_4 256
104 #define DEG_4 63
105 #define SEP_4 1
108 /* Array versions of the above information to make code run faster.
109 Relies on fact that TYPE_i == i. */
111 #define MAX_TYPES 5 /* Max number of types above. */
113 struct vm_random_poly_info
115 int seps[MAX_TYPES];
116 int degrees[MAX_TYPES];
119 static struct vm_random_poly_info vm_random_poly_info =
121 { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 },
122 { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }
125 static int32_t vm_randtbl[DEG_3 + 1] =
127 TYPE_3,
129 -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
130 1627687941, -179304937, -2073333483, 1780058412, -1989503057,
131 -615974602, 344556628, 939512070, -1249116260, 1507946756,
132 -812545463, 154635395, 1388815473, -1926676823, 525320961,
133 -1009028674, 968117788, -123449607, 1284210865, 435012392,
134 -2017506339, -911064859, -370259173, 1132637927, 1398500161,
135 -205601318,
138 /* Initialize the random number generator based on the given seed. If the
139 type is the trivial no-state-information type, just remember the seed.
140 Otherwise, initializes state[] based on the given "seed" via a linear
141 congruential generator. Then, the pointers are set to known locations
142 that are exactly rand_sep places apart. Lastly, it cycles the state
143 information a given number of times to get rid of any initial dependencies
144 introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
145 for default usage relies on values produced by this routine. */
146 int vm_srandom (unsigned int seed,
147 struct vm_random_data* buf)
149 int type;
150 int32_t *state;
151 long int i;
152 long int word;
153 int32_t *dst;
154 int kc;
156 if (buf == NULL)
157 goto fail;
158 type = buf->vm_rand_type;
159 if ((unsigned int) type >= MAX_TYPES)
160 goto fail;
162 state = buf->state;
163 /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */
164 if (seed == 0)
165 seed = 1;
166 state[0] = seed;
167 if (type == TYPE_0)
168 goto done;
170 dst = state;
171 word = seed;
172 kc = buf->vm_rand_deg;
173 for (i = 1; i < kc; ++i)
175 /* This does:
176 state[i] = (16807 * state[i - 1]) % 2147483647;
177 but avoids overflowing 31 bits. */
178 long int hi = word / 127773;
179 long int lo = word % 127773;
180 word = 16807 * lo - 2836 * hi;
181 if (word < 0)
182 word += 2147483647;
183 *++dst = word;
186 buf->fptr = &state[buf->vm_rand_sep];
187 buf->rptr = &state[0];
188 kc *= 10;
189 while (--kc >= 0)
191 vm_random (buf);
194 done:
195 return 0;
197 fail:
198 return -1;
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. Note that on return
206 from srandom, we set state[-1] to be the type multiplexed with the current
207 value of the rear pointer; this is so successive calls to initstate won't
208 lose this information and will be able to restart with setstate.
209 Note: The first thing we do is save the current state, if any, just like
210 setstate so that it doesn't matter when initstate is called.
211 Returns a pointer to the old state. */
212 int vm_initstate (unsigned int seed,
213 void* arg_state,
214 size_t n,
215 struct vm_random_data* buf)
217 int type;
218 int degree;
219 int separation;
220 int32_t *state;
222 if (buf == NULL)
223 goto fail;
225 if (n >= BREAK_3)
226 type = n < BREAK_4 ? TYPE_3 : TYPE_4;
227 else if (n < BREAK_1)
229 if (n < BREAK_0)
231 goto fail;
233 type = TYPE_0;
235 else
236 type = n < BREAK_2 ? TYPE_1 : TYPE_2;
238 degree = vm_random_poly_info.degrees[type];
239 separation = vm_random_poly_info.seps[type];
241 buf->vm_rand_type = type;
242 buf->vm_rand_sep = separation;
243 buf->vm_rand_deg = degree;
244 state = &((int32_t *) arg_state)[1]; /* First location. */
245 /* Must set END_PTR before srandom. */
246 buf->end_ptr = &state[degree];
248 buf->state = state;
250 vm_srandom (seed, buf);
252 state[-1] = TYPE_0;
253 if (type != TYPE_0)
254 state[-1] = (buf->rptr - state) * MAX_TYPES + type;
256 return 0;
258 fail:
259 return -1;
262 /* Restore the state from the given state array.
263 Note: It is important that we also remember the locations of the pointers
264 in the current state information, and restore the locations of the pointers
265 from the old state information. This is done by multiplexing the pointer
266 location into the zeroth word of the state information. Note that due
267 to the order in which things are done, it is OK to call setstate with the
268 same state as the current state
269 Returns a pointer to the old state information. */
270 int vm_setstate (void* arg_state,
271 struct vm_random_data* buf)
273 int32_t *new_state = (int32_t *) arg_state;
274 int type;
275 int old_type;
276 int32_t *old_state;
277 int degree;
278 int separation;
280 if (buf == NULL)
281 goto fail;
283 old_type = buf->vm_rand_type;
284 old_state = buf->state;
285 if (old_type == TYPE_0)
286 old_state[-1] = TYPE_0;
287 else
288 old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
290 type = new_state[0] % MAX_TYPES;
291 if (type < TYPE_0 || type >= TYPE_4)
292 goto fail;
294 buf->vm_rand_deg = degree = vm_random_poly_info.degrees[type];
295 buf->vm_rand_sep = separation = vm_random_poly_info.seps[type];
296 buf->vm_rand_type = type;
298 if (type != TYPE_0)
300 int rear = new_state[0] / MAX_TYPES;
301 buf->rptr = &new_state[rear];
302 buf->fptr = &new_state[(rear + separation) % degree];
304 buf->state = &new_state[1];
305 /* Set end_ptr too. */
306 buf->end_ptr = &new_state[degree];
308 return 0;
310 fail:
311 return -1;
314 /* If we are using the trivial TYPE_0 R.N.G., just do the old linear
315 congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
316 same in all the other cases due to all the global variables that have been
317 set up. The basic operation is to add the number at the rear pointer into
318 the one at the front pointer. Then both pointers are advanced to the next
319 location cyclically in the table. The value returned is the sum generated,
320 reduced to 31 bits by throwing away the "least random" low bit.
321 Note: The code takes advantage of the fact that both the front and
322 rear pointers can't wrap on the same call by not testing the rear
323 pointer if the front one has wrapped. Returns a 31-bit random number. */
325 int32_t vm_random (struct vm_random_data* buf)
327 int32_t *state;
328 int32_t result;
330 if (buf == NULL)
331 goto fail;
333 state = buf->state;
335 if (buf->vm_rand_type == TYPE_0)
337 int32_t val = state[0];
338 val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
339 state[0] = val;
340 result = val;
342 else
344 int32_t *fptr = buf->fptr;
345 int32_t *rptr = buf->rptr;
346 int32_t *end_ptr = buf->end_ptr;
347 int32_t val;
349 val = *fptr += *rptr;
350 /* Chucking least random bit. */
351 result = (val >> 1) & 0x7fffffff;
352 ++fptr;
353 if (fptr >= end_ptr)
355 fptr = state;
356 ++rptr;
358 else
360 ++rptr;
361 if (rptr >= end_ptr)
362 rptr = state;
364 buf->fptr = fptr;
365 buf->rptr = rptr;
367 return result;
369 fail:
370 return -1;
373 void vm_default_initstate( int seed,
374 struct vm_random_data* buf ) {
375 vm_initstate( seed,
376 vm_randtbl,
377 128,
378 buf );