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