Include string.h, supress a warning.
[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 <wilhelmi@ira.uka.de>.
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 <stdio.h>
43 #include <string.h>
44
45 #include "glib.h"
46
47
48 G_LOCK_DEFINE_STATIC (global_random);
49 static GRand* global_random = NULL;
50
51 /* Period parameters */  
52 #define N 624
53 #define M 397
54 #define MATRIX_A 0x9908b0df   /* constant vector a */
55 #define UPPER_MASK 0x80000000 /* most significant w-r bits */
56 #define LOWER_MASK 0x7fffffff /* least significant r bits */
57
58 /* Tempering parameters */   
59 #define TEMPERING_MASK_B 0x9d2c5680
60 #define TEMPERING_MASK_C 0xefc60000
61 #define TEMPERING_SHIFT_U(y)  (y >> 11)
62 #define TEMPERING_SHIFT_S(y)  (y << 7)
63 #define TEMPERING_SHIFT_T(y)  (y << 15)
64 #define TEMPERING_SHIFT_L(y)  (y >> 18)
65
66 static guint
67 get_random_version (void)
68 {
69   static gboolean initialized = FALSE;
70   static guint random_version;
71   
72   if (!initialized)
73     {
74       const gchar *version_string = g_getenv ("G_RANDOM_VERSION");
75       if (!version_string || version_string[0] == '\000' || 
76           strcmp (version_string, "2.2") == 0)
77         random_version = 22;
78       else if (strcmp (version_string, "2.0") == 0)
79         random_version = 20;
80       else
81         {
82           g_warning ("Unknown G_RANDOM_VERSION \"%s\". Using version 2.2.",
83                      version_string);
84           random_version = 22;
85         }
86       initialized = TRUE;
87     }
88   
89   return random_version;
90 }
91
92 /* This is called from g_thread_init(). It's used to
93  * initialize some static data in a threadsafe way.
94  */
95 void 
96 g_rand_init (void)
97 {
98   (void)get_random_version ();
99 }
100
101 struct _GRand
102 {
103   guint32 mt[N]; /* the array for the state vector  */
104   guint mti; 
105 };
106
107 /**
108  * g_rand_new_with_seed:
109  * @seed: a value to initialize the random number generator.
110  * 
111  * Creates a new random number generator initialized with @seed.
112  * 
113  * Return value: the new #GRand.
114  **/
115 GRand*
116 g_rand_new_with_seed (guint32 seed)
117 {
118   GRand *rand = g_new0 (GRand, 1);
119   g_rand_set_seed (rand, seed);
120   return rand;
121 }
122
123 /**
124  * g_rand_new:
125  * 
126  * Creates a new random number generator initialized with a seed taken
127  * either from <filename>/dev/urandom</filename> (if existing) or from 
128  * the current time (as a fallback).
129  * 
130  * Return value: the new #GRand.
131  **/
132 GRand* 
133 g_rand_new (void)
134 {
135   guint32 seed;
136   GTimeVal now;
137 #ifdef G_OS_UNIX
138   static gboolean dev_urandom_exists = TRUE;
139
140   if (dev_urandom_exists)
141     {
142       FILE* dev_urandom = fopen("/dev/urandom", "rb");
143       if (dev_urandom)
144         {
145           if (fread (&seed, sizeof (seed), 1, dev_urandom) != 1)
146             dev_urandom_exists = FALSE;
147           fclose (dev_urandom);
148         }       
149       else
150         dev_urandom_exists = FALSE;
151     }
152 #else
153   static gboolean dev_urandom_exists = FALSE;
154 #endif
155
156   if (!dev_urandom_exists)
157     {  
158       g_get_current_time (&now);
159       seed = now.tv_sec ^ now.tv_usec;
160     }
161
162   return g_rand_new_with_seed (seed);
163 }
164
165 /**
166  * g_rand_free:
167  * @rand_: a #GRand.
168  *
169  * Frees the memory allocated for the #GRand.
170  **/
171 void
172 g_rand_free (GRand* rand)
173 {
174   g_return_if_fail (rand != NULL);
175
176   g_free (rand);
177 }
178
179 /**
180  * g_rand_set_seed:
181  * @rand_: a #GRand.
182  * @seed: a value to reinitialize the random number generator.
183  *
184  * Sets the seed for the random number generator #GRand to @seed.
185  **/
186 void
187 g_rand_set_seed (GRand* rand, guint32 seed)
188 {
189   g_return_if_fail (rand != NULL);
190
191   switch (get_random_version ())
192     {
193     case 20:
194       /* setting initial seeds to mt[N] using         */
195       /* the generator Line 25 of Table 1 in          */
196       /* [KNUTH 1981, The Art of Computer Programming */
197       /*    Vol. 2 (2nd Ed.), pp102]                  */
198       
199       if (seed == 0) /* This would make the PRNG procude only zeros */
200         seed = 0x6b842128; /* Just set it to another number */
201       
202       rand->mt[0]= seed;
203       for (rand->mti=1; rand->mti<N; rand->mti++)
204         rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]);
205       
206       break;
207     case 22:
208       /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
209       /* In the previous version (see above), MSBs of the    */
210       /* seed affect only MSBs of the array mt[].            */
211       
212       rand->mt[0]= seed;
213       for (rand->mti=1; rand->mti<N; rand->mti++)
214         rand->mt[rand->mti] = 1812433253UL * 
215           (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti; 
216       break;
217     default:
218       g_assert_not_reached ();
219     }
220 }
221
222 /**
223  * g_rand_int:
224  * @rand_: a #GRand.
225  *
226  * Returns the next random #guint32 from @rand_ equally distributed over
227  * the range [0..2^32-1].
228  *
229  * Return value: A random number.
230  **/
231 guint32
232 g_rand_int (GRand* rand)
233 {
234   guint32 y;
235   static const guint32 mag01[2]={0x0, MATRIX_A};
236   /* mag01[x] = x * MATRIX_A  for x=0,1 */
237
238   g_return_val_if_fail (rand != NULL, 0);
239
240   if (rand->mti >= N) { /* generate N words at one time */
241     int kk;
242     
243     for (kk=0;kk<N-M;kk++) {
244       y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
245       rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
246     }
247     for (;kk<N-1;kk++) {
248       y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
249       rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
250     }
251     y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK);
252     rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
253     
254     rand->mti = 0;
255   }
256   
257   y = rand->mt[rand->mti++];
258   y ^= TEMPERING_SHIFT_U(y);
259   y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
260   y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
261   y ^= TEMPERING_SHIFT_L(y);
262   
263   return y; 
264 }
265
266 /* transform [0..2^32] -> [0..1] */
267 #define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
268
269 /**
270  * g_rand_int_range:
271  * @rand_: a #GRand.
272  * @begin: lower closed bound of the interval.
273  * @end: upper open bound of the interval.
274  *
275  * Returns the next random #gint32 from @rand_ equally distributed over
276  * the range [@begin..@end-1].
277  *
278  * Return value: A random number.
279  **/
280 gint32 
281 g_rand_int_range (GRand* rand, gint32 begin, gint32 end)
282 {
283   guint32 dist = end - begin;
284   guint32 random;
285
286   g_return_val_if_fail (rand != NULL, begin);
287   g_return_val_if_fail (end > begin, begin);
288
289   switch (get_random_version ())
290     {
291     case 20:
292       if (dist <= 0x10000L) /* 2^16 */
293         {
294           /* This method, which only calls g_rand_int once is only good
295            * for (end - begin) <= 2^16, because we only have 32 bits set
296            * from the one call to g_rand_int (). */
297           
298           /* we are using (trans + trans * trans), because g_rand_int only
299            * covers [0..2^32-1] and thus g_rand_int * trans only covers
300            * [0..1-2^-32], but the biggest double < 1 is 1-2^-52. 
301            */
302           
303           gdouble double_rand = g_rand_int (rand) * 
304             (G_RAND_DOUBLE_TRANSFORM +
305              G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM);
306           
307           random = (gint32) (double_rand * dist);
308         }
309       else
310         {
311           /* Now we use g_rand_double_range (), which will set 52 bits for
312              us, so that it is safe to round and still get a decent
313              distribution */
314           random = (gint32) g_rand_double_range (rand, 0, dist);
315         }
316       break;
317     case 22:
318       if (dist == 0)
319         random = 0;
320       else 
321         {
322           /* maxvalue is set to the predecessor of the greatest
323            * multiple of dist less or equal 2^32. */
324           guint32 maxvalue;
325           if (dist <= 0x80000000u) /* 2^31 */
326             {
327               /* maxvalue = 2^32 - 1 - (2^32 % dist) */
328               guint32 leftover = (0x80000000u % dist) * 2;
329               if (leftover >= dist) leftover -= dist;
330               maxvalue = 0xffffffffu - leftover;
331             }
332           else
333             maxvalue = dist - 1;
334           
335           do
336             random = g_rand_int (rand);
337           while (random > maxvalue);
338           
339           random %= dist;
340         }
341       break;
342     default:
343       random = 0;               /* Quiet GCC */
344       g_assert_not_reached ();
345     }      
346  
347   return begin + random;
348 }
349
350 /**
351  * g_rand_double:
352  * @rand_: a #GRand.
353  *
354  * Returns the next random #gdouble from @rand_ equally distributed over
355  * the range [0..1).
356  *
357  * Return value: A random number.
358  **/
359 gdouble 
360 g_rand_double (GRand* rand)
361 {    
362   /* We set all 52 bits after the point for this, not only the first
363      32. Thats why we need two calls to g_rand_int */
364   gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
365   retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM;
366
367   /* The following might happen due to very bad rounding luck, but
368    * actually this should be more than rare, we just try again then */
369   if (retval >= 1.0) 
370     return g_rand_double (rand);
371
372   return retval;
373 }
374
375 /**
376  * g_rand_double_range:
377  * @rand_: a #GRand.
378  * @begin: lower closed bound of the interval.
379  * @end: upper open bound of the interval.
380  *
381  * Returns the next random #gdouble from @rand_ equally distributed over
382  * the range [@begin..@end).
383  *
384  * Return value: A random number.
385  **/
386 gdouble 
387 g_rand_double_range (GRand* rand, gdouble begin, gdouble end)
388 {
389   return g_rand_double (rand) * (end - begin) + begin;
390 }
391
392 /**
393  * g_random_int:
394  *
395  * Return a random #guint32 equally distributed over the range
396  * [0..2^32-1].
397  *
398  * Return value: A random number.
399  **/
400 guint32
401 g_random_int (void)
402 {
403   guint32 result;
404   G_LOCK (global_random);
405   if (!global_random)
406     global_random = g_rand_new ();
407   
408   result = g_rand_int (global_random);
409   G_UNLOCK (global_random);
410   return result;
411 }
412
413 /**
414  * g_random_int_range:
415  * @begin: lower closed bound of the interval.
416  * @end: upper open bound of the interval.
417  *
418  * Returns a random #gint32 equally distributed over the range
419  * [@begin..@end-1].
420  *
421  * Return value: A random number.
422  **/
423 gint32 
424 g_random_int_range (gint32 begin, gint32 end)
425 {
426   gint32 result;
427   G_LOCK (global_random);
428   if (!global_random)
429     global_random = g_rand_new ();
430   
431   result = g_rand_int_range (global_random, begin, end);
432   G_UNLOCK (global_random);
433   return result;
434 }
435
436 /**
437  * g_random_double:
438  *
439  * Returns a random #gdouble equally distributed over the range [0..1).
440  *
441  * Return value: A random number.
442  **/
443 gdouble 
444 g_random_double (void)
445 {
446   double result;
447   G_LOCK (global_random);
448   if (!global_random)
449     global_random = g_rand_new ();
450   
451   result = g_rand_double (global_random);
452   G_UNLOCK (global_random);
453   return result;
454 }
455
456 /**
457  * g_random_double_range:
458  * @begin: lower closed bound of the interval.
459  * @end: upper open bound of the interval.
460  *
461  * Returns a random #gdouble equally distributed over the range [@begin..@end).
462  *
463  * Return value: A random number.
464  **/
465 gdouble 
466 g_random_double_range (gdouble begin, gdouble end)
467 {
468   double result;
469   G_LOCK (global_random);
470   if (!global_random)
471     global_random = g_rand_new ();
472  
473   result = g_rand_double_range (global_random, begin, end);
474   G_UNLOCK (global_random);
475   return result;
476 }
477
478 /**
479  * g_random_set_seed:
480  * @seed: a value to reinitialize the global random number generator.
481  * 
482  * Sets the seed for the global random number generator, which is used
483  * by the <function>g_random_*</function> functions, to @seed.
484  **/
485 void
486 g_random_set_seed (guint32 seed)
487 {
488   G_LOCK (global_random);
489   if (!global_random)
490     global_random = g_rand_new_with_seed (seed);
491   else
492     g_rand_set_seed (global_random, seed);
493   G_UNLOCK (global_random);
494 }
495