Make PLT-reduction work with gcc4, and don't include everything in
[platform/upstream/glib.git] / glib / grand.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /* Originally developed and coded by Makoto Matsumoto and Takuji
21  * Nishimura.  Please mail <matumoto@math.keio.ac.jp>, if you're using
22  * code from this file in your own programs or libraries.
23  * Further information on the Mersenne Twister can be found at
24  * http://www.math.keio.ac.jp/~matumoto/emt.html
25  * This code was adapted to glib by Sebastian Wilhelmi.
26  */
27
28 /*
29  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
30  * file for a list of people on the GLib Team.  See the ChangeLog
31  * files for a list of changes.  These files are distributed with
32  * GLib at ftp://ftp.gtk.org/pub/gtk/.  
33  */
34
35 /* 
36  * MT safe
37  */
38
39 #include "config.h"
40
41 #include <math.h>
42 #include <errno.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <sys/types.h>
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49
50 #include "glib.h"
51 #include "gthreadinit.h"
52 #include "galias.h"
53
54 #ifdef G_OS_WIN32
55 #include <process.h>            /* For getpid() */
56 #endif
57
58 G_LOCK_DEFINE_STATIC (global_random);
59 static GRand* global_random = NULL;
60
61 /* Period parameters */  
62 #define N 624
63 #define M 397
64 #define MATRIX_A 0x9908b0df   /* constant vector a */
65 #define UPPER_MASK 0x80000000 /* most significant w-r bits */
66 #define LOWER_MASK 0x7fffffff /* least significant r bits */
67
68 /* Tempering parameters */   
69 #define TEMPERING_MASK_B 0x9d2c5680
70 #define TEMPERING_MASK_C 0xefc60000
71 #define TEMPERING_SHIFT_U(y)  (y >> 11)
72 #define TEMPERING_SHIFT_S(y)  (y << 7)
73 #define TEMPERING_SHIFT_T(y)  (y << 15)
74 #define TEMPERING_SHIFT_L(y)  (y >> 18)
75
76 static guint
77 get_random_version (void)
78 {
79   static gboolean initialized = FALSE;
80   static guint random_version;
81   
82   if (!initialized)
83     {
84       const gchar *version_string = g_getenv ("G_RANDOM_VERSION");
85       if (!version_string || version_string[0] == '\000' || 
86           strcmp (version_string, "2.2") == 0)
87         random_version = 22;
88       else if (strcmp (version_string, "2.0") == 0)
89         random_version = 20;
90       else
91         {
92           g_warning ("Unknown G_RANDOM_VERSION \"%s\". Using version 2.2.",
93                      version_string);
94           random_version = 22;
95         }
96       initialized = TRUE;
97     }
98   
99   return random_version;
100 }
101
102 /* This is called from g_thread_init(). It's used to
103  * initialize some static data in a threadsafe way.
104  */
105 void 
106 _g_rand_thread_init (void)
107 {
108   (void)get_random_version ();
109 }
110
111 struct _GRand
112 {
113   guint32 mt[N]; /* the array for the state vector  */
114   guint mti; 
115 };
116
117 /**
118  * g_rand_new_with_seed:
119  * @seed: a value to initialize the random number generator.
120  * 
121  * Creates a new random number generator initialized with @seed.
122  * 
123  * Return value: the new #GRand.
124  **/
125 GRand*
126 g_rand_new_with_seed (guint32 seed)
127 {
128   GRand *rand = g_new0 (GRand, 1);
129   g_rand_set_seed (rand, seed);
130   return rand;
131 }
132
133 /**
134  * g_rand_new_with_seed_array:
135  * @seed: an array of seeds to initialize the random number generator.
136  * @seed_length: an array of seeds to initialize the random number generator.
137  * 
138  * Creates a new random number generator initialized with @seed.
139  * 
140  * Return value: the new #GRand.
141  *
142  * Since: 2.4
143  **/
144 GRand*
145 g_rand_new_with_seed_array (const guint32 *seed, guint seed_length)
146 {
147   GRand *rand = g_new0 (GRand, 1);
148   g_rand_set_seed_array (rand, seed, seed_length);
149   return rand;
150 }
151
152 /**
153  * g_rand_new:
154  * 
155  * Creates a new random number generator initialized with a seed taken
156  * either from <filename>/dev/urandom</filename> (if existing) or from 
157  * the current time (as a fallback).
158  * 
159  * Return value: the new #GRand.
160  **/
161 GRand* 
162 g_rand_new (void)
163 {
164   guint32 seed[4];
165   GTimeVal now;
166 #ifdef G_OS_UNIX
167   static gboolean dev_urandom_exists = TRUE;
168
169   if (dev_urandom_exists)
170     {
171       FILE* dev_urandom;
172
173       do
174         {
175           errno = 0;
176           dev_urandom = fopen("/dev/urandom", "rb");
177         }
178       while G_UNLIKELY (errno == EINTR);
179
180       if (dev_urandom)
181         {
182           int r;
183
184           do
185             {
186               errno = 0;
187               r = fread (seed, sizeof (seed), 1, dev_urandom);
188             }
189           while G_UNLIKELY (errno == EINTR);
190
191           if (r != 1)
192             dev_urandom_exists = FALSE;
193
194           do
195             {
196               errno = 0;
197               fclose (dev_urandom);
198             }
199           while G_UNLIKELY (errno == EINTR);
200         }       
201       else
202         dev_urandom_exists = FALSE;
203     }
204 #else
205   static gboolean dev_urandom_exists = FALSE;
206 #endif
207
208   if (!dev_urandom_exists)
209     {  
210       g_get_current_time (&now);
211       seed[0] = now.tv_sec;
212       seed[1] = now.tv_usec;
213       seed[2] = getpid ();
214 #ifdef G_OS_UNIX
215       seed[3] = getppid ();
216 #else
217       seed[3] = 0;
218 #endif
219     }
220
221   return g_rand_new_with_seed_array (seed, 4);
222 }
223
224 /**
225  * g_rand_free:
226  * @rand_: a #GRand.
227  *
228  * Frees the memory allocated for the #GRand.
229  **/
230 void
231 g_rand_free (GRand* rand)
232 {
233   g_return_if_fail (rand != NULL);
234
235   g_free (rand);
236 }
237
238 /**
239  * g_rand_copy:
240  * @rand_: a #GRand.
241  *
242  * Copies a #GRand into a new one with the same exact state as before.
243  * This way you can take a snapshot of the random number generator for
244  * replaying later.
245  *
246  * Return value: the new #GRand.
247  *
248  * Since: 2.4
249  **/
250 GRand *
251 g_rand_copy (GRand* rand)
252 {
253   GRand* new_rand;
254
255   g_return_val_if_fail (rand != NULL, NULL);
256
257   new_rand = g_new0 (GRand, 1);
258   memcpy (new_rand, rand, sizeof (GRand));
259
260   return new_rand;
261 }
262
263 /**
264  * g_rand_set_seed:
265  * @rand_: a #GRand.
266  * @seed: a value to reinitialize the random number generator.
267  *
268  * Sets the seed for the random number generator #GRand to @seed.
269  **/
270 void
271 g_rand_set_seed (GRand* rand, guint32 seed)
272 {
273   g_return_if_fail (rand != NULL);
274
275   switch (get_random_version ())
276     {
277     case 20:
278       /* setting initial seeds to mt[N] using         */
279       /* the generator Line 25 of Table 1 in          */
280       /* [KNUTH 1981, The Art of Computer Programming */
281       /*    Vol. 2 (2nd Ed.), pp102]                  */
282       
283       if (seed == 0) /* This would make the PRNG procude only zeros */
284         seed = 0x6b842128; /* Just set it to another number */
285       
286       rand->mt[0]= seed;
287       for (rand->mti=1; rand->mti<N; rand->mti++)
288         rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]);
289       
290       break;
291     case 22:
292       /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
293       /* In the previous version (see above), MSBs of the    */
294       /* seed affect only MSBs of the array mt[].            */
295       
296       rand->mt[0]= seed;
297       for (rand->mti=1; rand->mti<N; rand->mti++)
298         rand->mt[rand->mti] = 1812433253UL * 
299           (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti; 
300       break;
301     default:
302       g_assert_not_reached ();
303     }
304 }
305
306 /**
307  * g_rand_set_seed_array:
308  * @rand_: a #GRand.
309  * @seed: array to initialize with
310  * @seed_length: length of array
311  *
312  * Initializes the random number generator by an array of
313  * longs.  Array can be of arbitrary size, though only the
314  * first 624 values are taken.  This function is useful
315  * if you have many low entropy seeds, or if you require more then
316  * 32bits of actual entropy for your application.
317  *
318  * Since: 2.4
319  **/
320 void
321 g_rand_set_seed_array (GRand* rand, const guint32 *seed, guint seed_length)
322 {
323   int i, j, k;
324
325   g_return_if_fail (rand != NULL);
326   g_return_if_fail (seed_length >= 1);
327
328   g_rand_set_seed (rand, 19650218UL);
329
330   i=1; j=0;
331   k = (N>seed_length ? N : seed_length);
332   for (; k; k--)
333     {
334       rand->mt[i] = (rand->mt[i] ^
335                      ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1664525UL))
336               + seed[j] + j; /* non linear */
337       rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
338       i++; j++;
339       if (i>=N)
340         {
341           rand->mt[0] = rand->mt[N-1];
342           i=1;
343         }
344       if (j>=seed_length)
345         j=0;
346     }
347   for (k=N-1; k; k--)
348     {
349       rand->mt[i] = (rand->mt[i] ^
350                      ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1566083941UL))
351               - i; /* non linear */
352       rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
353       i++;
354       if (i>=N)
355         {
356           rand->mt[0] = rand->mt[N-1];
357           i=1;
358         }
359     }
360
361   rand->mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
362 }
363
364 /**
365  * g_rand_int:
366  * @rand_: a #GRand.
367  *
368  * Returns the next random #guint32 from @rand_ equally distributed over
369  * the range [0..2^32-1].
370  *
371  * Return value: A random number.
372  **/
373 guint32
374 g_rand_int (GRand* rand)
375 {
376   guint32 y;
377   static const guint32 mag01[2]={0x0, MATRIX_A};
378   /* mag01[x] = x * MATRIX_A  for x=0,1 */
379
380   g_return_val_if_fail (rand != NULL, 0);
381
382   if (rand->mti >= N) { /* generate N words at one time */
383     int kk;
384     
385     for (kk=0;kk<N-M;kk++) {
386       y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
387       rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
388     }
389     for (;kk<N-1;kk++) {
390       y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
391       rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
392     }
393     y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK);
394     rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
395     
396     rand->mti = 0;
397   }
398   
399   y = rand->mt[rand->mti++];
400   y ^= TEMPERING_SHIFT_U(y);
401   y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
402   y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
403   y ^= TEMPERING_SHIFT_L(y);
404   
405   return y; 
406 }
407
408 /* transform [0..2^32] -> [0..1] */
409 #define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
410
411 /**
412  * g_rand_int_range:
413  * @rand_: a #GRand.
414  * @begin: lower closed bound of the interval.
415  * @end: upper open bound of the interval.
416  *
417  * Returns the next random #gint32 from @rand_ equally distributed over
418  * the range [@begin..@end-1].
419  *
420  * Return value: A random number.
421  **/
422 gint32 
423 g_rand_int_range (GRand* rand, gint32 begin, gint32 end)
424 {
425   guint32 dist = end - begin;
426   guint32 random;
427
428   g_return_val_if_fail (rand != NULL, begin);
429   g_return_val_if_fail (end > begin, begin);
430
431   switch (get_random_version ())
432     {
433     case 20:
434       if (dist <= 0x10000L) /* 2^16 */
435         {
436           /* This method, which only calls g_rand_int once is only good
437            * for (end - begin) <= 2^16, because we only have 32 bits set
438            * from the one call to g_rand_int (). */
439           
440           /* we are using (trans + trans * trans), because g_rand_int only
441            * covers [0..2^32-1] and thus g_rand_int * trans only covers
442            * [0..1-2^-32], but the biggest double < 1 is 1-2^-52. 
443            */
444           
445           gdouble double_rand = g_rand_int (rand) * 
446             (G_RAND_DOUBLE_TRANSFORM +
447              G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM);
448           
449           random = (gint32) (double_rand * dist);
450         }
451       else
452         {
453           /* Now we use g_rand_double_range (), which will set 52 bits for
454              us, so that it is safe to round and still get a decent
455              distribution */
456           random = (gint32) g_rand_double_range (rand, 0, dist);
457         }
458       break;
459     case 22:
460       if (dist == 0)
461         random = 0;
462       else 
463         {
464           /* maxvalue is set to the predecessor of the greatest
465            * multiple of dist less or equal 2^32. */
466           guint32 maxvalue;
467           if (dist <= 0x80000000u) /* 2^31 */
468             {
469               /* maxvalue = 2^32 - 1 - (2^32 % dist) */
470               guint32 leftover = (0x80000000u % dist) * 2;
471               if (leftover >= dist) leftover -= dist;
472               maxvalue = 0xffffffffu - leftover;
473             }
474           else
475             maxvalue = dist - 1;
476           
477           do
478             random = g_rand_int (rand);
479           while (random > maxvalue);
480           
481           random %= dist;
482         }
483       break;
484     default:
485       random = 0;               /* Quiet GCC */
486       g_assert_not_reached ();
487     }      
488  
489   return begin + random;
490 }
491
492 /**
493  * g_rand_double:
494  * @rand_: a #GRand.
495  *
496  * Returns the next random #gdouble from @rand_ equally distributed over
497  * the range [0..1).
498  *
499  * Return value: A random number.
500  **/
501 gdouble 
502 g_rand_double (GRand* rand)
503 {    
504   /* We set all 52 bits after the point for this, not only the first
505      32. Thats why we need two calls to g_rand_int */
506   gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
507   retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM;
508
509   /* The following might happen due to very bad rounding luck, but
510    * actually this should be more than rare, we just try again then */
511   if (retval >= 1.0) 
512     return g_rand_double (rand);
513
514   return retval;
515 }
516
517 /**
518  * g_rand_double_range:
519  * @rand_: a #GRand.
520  * @begin: lower closed bound of the interval.
521  * @end: upper open bound of the interval.
522  *
523  * Returns the next random #gdouble from @rand_ equally distributed over
524  * the range [@begin..@end).
525  *
526  * Return value: A random number.
527  **/
528 gdouble 
529 g_rand_double_range (GRand* rand, gdouble begin, gdouble end)
530 {
531   return g_rand_double (rand) * (end - begin) + begin;
532 }
533
534 /**
535  * g_random_int:
536  *
537  * Return a random #guint32 equally distributed over the range
538  * [0..2^32-1].
539  *
540  * Return value: A random number.
541  **/
542 guint32
543 g_random_int (void)
544 {
545   guint32 result;
546   G_LOCK (global_random);
547   if (!global_random)
548     global_random = g_rand_new ();
549   
550   result = g_rand_int (global_random);
551   G_UNLOCK (global_random);
552   return result;
553 }
554
555 /**
556  * g_random_int_range:
557  * @begin: lower closed bound of the interval.
558  * @end: upper open bound of the interval.
559  *
560  * Returns a random #gint32 equally distributed over the range
561  * [@begin..@end-1].
562  *
563  * Return value: A random number.
564  **/
565 gint32 
566 g_random_int_range (gint32 begin, gint32 end)
567 {
568   gint32 result;
569   G_LOCK (global_random);
570   if (!global_random)
571     global_random = g_rand_new ();
572   
573   result = g_rand_int_range (global_random, begin, end);
574   G_UNLOCK (global_random);
575   return result;
576 }
577
578 /**
579  * g_random_double:
580  *
581  * Returns a random #gdouble equally distributed over the range [0..1).
582  *
583  * Return value: A random number.
584  **/
585 gdouble 
586 g_random_double (void)
587 {
588   double result;
589   G_LOCK (global_random);
590   if (!global_random)
591     global_random = g_rand_new ();
592   
593   result = g_rand_double (global_random);
594   G_UNLOCK (global_random);
595   return result;
596 }
597
598 /**
599  * g_random_double_range:
600  * @begin: lower closed bound of the interval.
601  * @end: upper open bound of the interval.
602  *
603  * Returns a random #gdouble equally distributed over the range [@begin..@end).
604  *
605  * Return value: A random number.
606  **/
607 gdouble 
608 g_random_double_range (gdouble begin, gdouble end)
609 {
610   double result;
611   G_LOCK (global_random);
612   if (!global_random)
613     global_random = g_rand_new ();
614  
615   result = g_rand_double_range (global_random, begin, end);
616   G_UNLOCK (global_random);
617   return result;
618 }
619
620 /**
621  * g_random_set_seed:
622  * @seed: a value to reinitialize the global random number generator.
623  * 
624  * Sets the seed for the global random number generator, which is used
625  * by the <function>g_random_*</function> functions, to @seed.
626  **/
627 void
628 g_random_set_seed (guint32 seed)
629 {
630   G_LOCK (global_random);
631   if (!global_random)
632     global_random = g_rand_new_with_seed (seed);
633   else
634     g_rand_set_seed (global_random, seed);
635   G_UNLOCK (global_random);
636 }
637
638
639 #define __G_RAND_C__
640 #include "galiasdef.c"