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