Ruby  2.0.0p247(2013-06-27revision41674)
random.c
Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   random.c -
00004 
00005   $Author: nagachika $
00006   created at: Fri Dec 24 16:39:21 JST 1993
00007 
00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
00009 
00010 **********************************************************************/
00011 
00012 /*
00013 This is based on trimmed version of MT19937.  To get the original version,
00014 contact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.
00015 
00016 The original copyright notice follows.
00017 
00018    A C-program for MT19937, with initialization improved 2002/2/10.
00019    Coded by Takuji Nishimura and Makoto Matsumoto.
00020    This is a faster version by taking Shawn Cokus's optimization,
00021    Matthe Bellew's simplification, Isaku Wada's real version.
00022 
00023    Before using, initialize the state by using init_genrand(mt, seed)
00024    or init_by_array(mt, init_key, key_length).
00025 
00026    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
00027    All rights reserved.
00028 
00029    Redistribution and use in source and binary forms, with or without
00030    modification, are permitted provided that the following conditions
00031    are met:
00032 
00033      1. Redistributions of source code must retain the above copyright
00034         notice, this list of conditions and the following disclaimer.
00035 
00036      2. Redistributions in binary form must reproduce the above copyright
00037         notice, this list of conditions and the following disclaimer in the
00038         documentation and/or other materials provided with the distribution.
00039 
00040      3. The names of its contributors may not be used to endorse or promote
00041         products derived from this software without specific prior written
00042         permission.
00043 
00044    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00045    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00046    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00047    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00048    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00049    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00050    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00051    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00052    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00053    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00054    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00055 
00056 
00057    Any feedback is very welcome.
00058    http://www.math.keio.ac.jp/matumoto/emt.html
00059    email: matumoto@math.keio.ac.jp
00060 */
00061 
00062 #include "ruby/ruby.h"
00063 
00064 #include <limits.h>
00065 #ifdef HAVE_UNISTD_H
00066 #include <unistd.h>
00067 #endif
00068 #include <time.h>
00069 #include <sys/types.h>
00070 #include <sys/stat.h>
00071 #ifdef HAVE_FCNTL_H
00072 #include <fcntl.h>
00073 #endif
00074 #include <math.h>
00075 #include <errno.h>
00076 #if defined(HAVE_SYS_TIME_H)
00077 #include <sys/time.h>
00078 #endif
00079 
00080 #ifdef _WIN32
00081 # if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0400
00082 #  undef _WIN32_WINNT
00083 #  define _WIN32_WINNT 0x400
00084 #  undef __WINCRYPT_H__
00085 # endif
00086 #include <wincrypt.h>
00087 #endif
00088 
00089 typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
00090 
00091 /* Period parameters */
00092 #define N 624
00093 #define M 397
00094 #define MATRIX_A 0x9908b0dfU    /* constant vector a */
00095 #define UMASK 0x80000000U       /* most significant w-r bits */
00096 #define LMASK 0x7fffffffU       /* least significant r bits */
00097 #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
00098 #define TWIST(u,v) ((MIXBITS((u),(v)) >> 1) ^ ((v)&1U ? MATRIX_A : 0U))
00099 
00100 enum {MT_MAX_STATE = N};
00101 
00102 struct MT {
00103     /* assume int is enough to store 32bits */
00104     unsigned int state[N]; /* the array for the state vector  */
00105     unsigned int *next;
00106     int left;
00107 };
00108 
00109 #define genrand_initialized(mt) ((mt)->next != 0)
00110 #define uninit_genrand(mt) ((mt)->next = 0)
00111 
00112 /* initializes state[N] with a seed */
00113 static void
00114 init_genrand(struct MT *mt, unsigned int s)
00115 {
00116     int j;
00117     mt->state[0] = s & 0xffffffffU;
00118     for (j=1; j<N; j++) {
00119         mt->state[j] = (1812433253U * (mt->state[j-1] ^ (mt->state[j-1] >> 30)) + j);
00120         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00121         /* In the previous versions, MSBs of the seed affect   */
00122         /* only MSBs of the array state[].                     */
00123         /* 2002/01/09 modified by Makoto Matsumoto             */
00124         mt->state[j] &= 0xffffffff;  /* for >32 bit machines */
00125     }
00126     mt->left = 1;
00127     mt->next = mt->state + N;
00128 }
00129 
00130 /* initialize by an array with array-length */
00131 /* init_key is the array for initializing keys */
00132 /* key_length is its length */
00133 /* slight change for C++, 2004/2/26 */
00134 static void
00135 init_by_array(struct MT *mt, unsigned int init_key[], int key_length)
00136 {
00137     int i, j, k;
00138     init_genrand(mt, 19650218U);
00139     i=1; j=0;
00140     k = (N>key_length ? N : key_length);
00141     for (; k; k--) {
00142         mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1664525U))
00143           + init_key[j] + j; /* non linear */
00144         mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
00145         i++; j++;
00146         if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
00147         if (j>=key_length) j=0;
00148     }
00149     for (k=N-1; k; k--) {
00150         mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1566083941U))
00151           - i; /* non linear */
00152         mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
00153         i++;
00154         if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
00155     }
00156 
00157     mt->state[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
00158 }
00159 
00160 static void
00161 next_state(struct MT *mt)
00162 {
00163     unsigned int *p = mt->state;
00164     int j;
00165 
00166     mt->left = N;
00167     mt->next = mt->state;
00168 
00169     for (j=N-M+1; --j; p++)
00170         *p = p[M] ^ TWIST(p[0], p[1]);
00171 
00172     for (j=M; --j; p++)
00173         *p = p[M-N] ^ TWIST(p[0], p[1]);
00174 
00175     *p = p[M-N] ^ TWIST(p[0], mt->state[0]);
00176 }
00177 
00178 /* generates a random number on [0,0xffffffff]-interval */
00179 static unsigned int
00180 genrand_int32(struct MT *mt)
00181 {
00182     /* mt must be initialized */
00183     unsigned int y;
00184 
00185     if (--mt->left <= 0) next_state(mt);
00186     y = *mt->next++;
00187 
00188     /* Tempering */
00189     y ^= (y >> 11);
00190     y ^= (y << 7) & 0x9d2c5680;
00191     y ^= (y << 15) & 0xefc60000;
00192     y ^= (y >> 18);
00193 
00194     return y;
00195 }
00196 
00197 /* generates a random number on [0,1) with 53-bit resolution*/
00198 static double
00199 genrand_real(struct MT *mt)
00200 {
00201     /* mt must be initialized */
00202     unsigned int a = genrand_int32(mt)>>5, b = genrand_int32(mt)>>6;
00203     return(a*67108864.0+b)*(1.0/9007199254740992.0);
00204 }
00205 
00206 /* generates a random number on [0,1] with 53-bit resolution*/
00207 static double int_pair_to_real_inclusive(unsigned int a, unsigned int b);
00208 static double
00209 genrand_real2(struct MT *mt)
00210 {
00211     /* mt must be initialized */
00212     unsigned int a = genrand_int32(mt), b = genrand_int32(mt);
00213     return int_pair_to_real_inclusive(a, b);
00214 }
00215 
00216 /* These real versions are due to Isaku Wada, 2002/01/09 added */
00217 
00218 #undef N
00219 #undef M
00220 
00221 typedef struct {
00222     VALUE seed;
00223     struct MT mt;
00224 } rb_random_t;
00225 
00226 #define DEFAULT_SEED_CNT 4
00227 
00228 static rb_random_t default_rand;
00229 
00230 static VALUE rand_init(struct MT *mt, VALUE vseed);
00231 static VALUE random_seed(void);
00232 
00233 static rb_random_t *
00234 rand_start(rb_random_t *r)
00235 {
00236     struct MT *mt = &r->mt;
00237     if (!genrand_initialized(mt)) {
00238         r->seed = rand_init(mt, random_seed());
00239     }
00240     return r;
00241 }
00242 
00243 static struct MT *
00244 default_mt(void)
00245 {
00246     return &rand_start(&default_rand)->mt;
00247 }
00248 
00249 unsigned int
00250 rb_genrand_int32(void)
00251 {
00252     struct MT *mt = default_mt();
00253     return genrand_int32(mt);
00254 }
00255 
00256 double
00257 rb_genrand_real(void)
00258 {
00259     struct MT *mt = default_mt();
00260     return genrand_real(mt);
00261 }
00262 
00263 #define BDIGITS(x) (RBIGNUM_DIGITS(x))
00264 #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
00265 #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
00266 #define DIGSPERINT (SIZEOF_INT/SIZEOF_BDIGITS)
00267 #define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)
00268 #define BIGDN(x) RSHIFT((x),BITSPERDIG)
00269 #define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))
00270 #define BDIGMAX ((BDIGIT)-1)
00271 
00272 #define roomof(n, m) (int)(((n)+(m)-1) / (m))
00273 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
00274 #define SIZEOF_INT32 (31/CHAR_BIT + 1)
00275 
00276 static double
00277 int_pair_to_real_inclusive(unsigned int a, unsigned int b)
00278 {
00279     VALUE x = rb_big_new(roomof(64, BITSPERDIG), 1);
00280     VALUE m = rb_big_new(roomof(53, BITSPERDIG), 1);
00281     BDIGIT *xd = BDIGITS(x);
00282     int i = 0;
00283     double r;
00284 
00285     xd[i++] = (BDIGIT)b;
00286 #if BITSPERDIG < 32
00287     xd[i++] = (BDIGIT)(b >> BITSPERDIG);
00288 #endif
00289     xd[i++] = (BDIGIT)a;
00290 #if BITSPERDIG < 32
00291     xd[i++] = (BDIGIT)(a >> BITSPERDIG);
00292 #endif
00293     xd = BDIGITS(m);
00294 #if BITSPERDIG < 53
00295     MEMZERO(xd, BDIGIT, roomof(53, BITSPERDIG) - 1);
00296 #endif
00297     xd[53 / BITSPERDIG] = 1 << 53 % BITSPERDIG;
00298     xd[0] |= 1;
00299     x = rb_big_mul(x, m);
00300     if (FIXNUM_P(x)) {
00301 #if CHAR_BIT * SIZEOF_LONG > 64
00302         r = (double)(FIX2ULONG(x) >> 64);
00303 #else
00304         return 0.0;
00305 #endif
00306     }
00307     else {
00308 #if 64 % BITSPERDIG == 0
00309         long len = RBIGNUM_LEN(x);
00310         xd = BDIGITS(x);
00311         MEMMOVE(xd, xd + 64 / BITSPERDIG, BDIGIT, len - 64 / BITSPERDIG);
00312         MEMZERO(xd + len - 64 / BITSPERDIG, BDIGIT, 64 / BITSPERDIG);
00313         r = rb_big2dbl(x);
00314 #else
00315         x = rb_big_rshift(x, INT2FIX(64));
00316         if (FIXNUM_P(x)) {
00317             r = (double)FIX2ULONG(x);
00318         }
00319         else {
00320             r = rb_big2dbl(x);
00321         }
00322 #endif
00323     }
00324     return ldexp(r, -53);
00325 }
00326 
00327 VALUE rb_cRandom;
00328 #define id_minus '-'
00329 #define id_plus  '+'
00330 static ID id_rand, id_bytes;
00331 
00332 /* :nodoc: */
00333 static void
00334 random_mark(void *ptr)
00335 {
00336     rb_gc_mark(((rb_random_t *)ptr)->seed);
00337 }
00338 
00339 static void
00340 random_free(void *ptr)
00341 {
00342     if (ptr != &default_rand)
00343         xfree(ptr);
00344 }
00345 
00346 static size_t
00347 random_memsize(const void *ptr)
00348 {
00349     return ptr ? sizeof(rb_random_t) : 0;
00350 }
00351 
00352 static const rb_data_type_t random_data_type = {
00353     "random",
00354     {
00355         random_mark,
00356         random_free,
00357         random_memsize,
00358     },
00359 };
00360 
00361 static rb_random_t *
00362 get_rnd(VALUE obj)
00363 {
00364     rb_random_t *ptr;
00365     TypedData_Get_Struct(obj, rb_random_t, &random_data_type, ptr);
00366     return ptr;
00367 }
00368 
00369 static rb_random_t *
00370 try_get_rnd(VALUE obj)
00371 {
00372     if (obj == rb_cRandom) {
00373         return rand_start(&default_rand);
00374     }
00375     if (!rb_typeddata_is_kind_of(obj, &random_data_type)) return NULL;
00376     return DATA_PTR(obj);
00377 }
00378 
00379 /* :nodoc: */
00380 static VALUE
00381 random_alloc(VALUE klass)
00382 {
00383     rb_random_t *rnd;
00384     VALUE obj = TypedData_Make_Struct(klass, rb_random_t, &random_data_type, rnd);
00385     rnd->seed = INT2FIX(0);
00386     return obj;
00387 }
00388 
00389 static VALUE
00390 rand_init(struct MT *mt, VALUE vseed)
00391 {
00392     volatile VALUE seed;
00393     long blen = 0;
00394     long fixnum_seed;
00395     int i, j, len;
00396     unsigned int buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;
00397 
00398     seed = rb_to_int(vseed);
00399     switch (TYPE(seed)) {
00400       case T_FIXNUM:
00401         len = 1;
00402         fixnum_seed = FIX2LONG(seed);
00403         if (fixnum_seed < 0)
00404             fixnum_seed = -fixnum_seed;
00405         buf[0] = (unsigned int)(fixnum_seed & 0xffffffff);
00406 #if SIZEOF_LONG > SIZEOF_INT32
00407         if ((long)(int32_t)fixnum_seed != fixnum_seed) {
00408             if ((buf[1] = (unsigned int)(fixnum_seed >> 32)) != 0) ++len;
00409         }
00410 #endif
00411         break;
00412       case T_BIGNUM:
00413         blen = RBIGNUM_LEN(seed);
00414         if (blen == 0) {
00415             len = 1;
00416         }
00417         else {
00418             if (blen > MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS)
00419                 blen = MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS;
00420             len = roomof((int)blen * SIZEOF_BDIGITS, SIZEOF_INT32);
00421         }
00422         /* allocate ints for init_by_array */
00423         if (len > numberof(buf0)) buf = ALLOC_N(unsigned int, len);
00424         memset(buf, 0, len * sizeof(*buf));
00425         len = 0;
00426         for (i = (int)(blen-1); 0 <= i; i--) {
00427             j = i * SIZEOF_BDIGITS / SIZEOF_INT32;
00428 #if SIZEOF_BDIGITS < SIZEOF_INT32
00429             buf[j] <<= BITSPERDIG;
00430 #endif
00431             buf[j] |= RBIGNUM_DIGITS(seed)[i];
00432             if (!len && buf[j]) len = j;
00433         }
00434         ++len;
00435         break;
00436       default:
00437         rb_raise(rb_eTypeError, "failed to convert %s into Integer",
00438                  rb_obj_classname(vseed));
00439     }
00440     if (len <= 1) {
00441         init_genrand(mt, buf[0]);
00442     }
00443     else {
00444         if (buf[len-1] == 1) /* remove leading-zero-guard */
00445             len--;
00446         init_by_array(mt, buf, len);
00447     }
00448     if (buf != buf0) xfree(buf);
00449     return seed;
00450 }
00451 
00452 /*
00453  * call-seq:
00454  *   Random.new(seed = Random.new_seed) -> prng
00455  *
00456  * Creates a new PRNG using +seed+ to set the initial state. If +seed+ is
00457  * omitted, the generator is initialized with Random.new_seed.
00458  *
00459  * See Random.srand for more information on the use of seed values.
00460  */
00461 static VALUE
00462 random_init(int argc, VALUE *argv, VALUE obj)
00463 {
00464     VALUE vseed;
00465     rb_random_t *rnd = get_rnd(obj);
00466 
00467     if (argc == 0) {
00468         rb_check_frozen(obj);
00469         vseed = random_seed();
00470     }
00471     else {
00472         rb_scan_args(argc, argv, "01", &vseed);
00473         rb_check_copyable(obj, vseed);
00474     }
00475     rnd->seed = rand_init(&rnd->mt, vseed);
00476     return obj;
00477 }
00478 
00479 #define DEFAULT_SEED_LEN (DEFAULT_SEED_CNT * (int)sizeof(int))
00480 
00481 #if defined(S_ISCHR) && !defined(DOSISH)
00482 # define USE_DEV_URANDOM 1
00483 #else
00484 # define USE_DEV_URANDOM 0
00485 #endif
00486 
00487 static void
00488 fill_random_seed(unsigned int seed[DEFAULT_SEED_CNT])
00489 {
00490     static int n = 0;
00491     struct timeval tv;
00492 #if USE_DEV_URANDOM
00493     int fd;
00494     struct stat statbuf;
00495 #elif defined(_WIN32)
00496     HCRYPTPROV prov;
00497 #endif
00498 
00499     memset(seed, 0, DEFAULT_SEED_LEN);
00500 
00501 #if USE_DEV_URANDOM
00502     if ((fd = rb_cloexec_open("/dev/urandom", O_RDONLY
00503 #ifdef O_NONBLOCK
00504             |O_NONBLOCK
00505 #endif
00506 #ifdef O_NOCTTY
00507             |O_NOCTTY
00508 #endif
00509             , 0)) >= 0) {
00510         rb_update_max_fd(fd);
00511         if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
00512             if (read(fd, seed, DEFAULT_SEED_LEN) < DEFAULT_SEED_LEN) {
00513                 /* abandon */;
00514             }
00515         }
00516         close(fd);
00517     }
00518 #elif defined(_WIN32)
00519     if (CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
00520         CryptGenRandom(prov, DEFAULT_SEED_LEN, (void *)seed);
00521         CryptReleaseContext(prov, 0);
00522     }
00523 #endif
00524 
00525     gettimeofday(&tv, 0);
00526     seed[0] ^= tv.tv_usec;
00527     seed[1] ^= (unsigned int)tv.tv_sec;
00528 #if SIZEOF_TIME_T > SIZEOF_INT
00529     seed[0] ^= (unsigned int)((time_t)tv.tv_sec >> SIZEOF_INT * CHAR_BIT);
00530 #endif
00531     seed[2] ^= getpid() ^ (n++ << 16);
00532     seed[3] ^= (unsigned int)(VALUE)&seed;
00533 #if SIZEOF_VOIDP > SIZEOF_INT
00534     seed[2] ^= (unsigned int)((VALUE)&seed >> SIZEOF_INT * CHAR_BIT);
00535 #endif
00536 }
00537 
00538 static VALUE
00539 make_seed_value(const void *ptr)
00540 {
00541     const long len = DEFAULT_SEED_LEN/SIZEOF_BDIGITS;
00542     BDIGIT *digits;
00543     NEWOBJ_OF(big, struct RBignum, rb_cBignum, T_BIGNUM);
00544 
00545     RBIGNUM_SET_SIGN(big, 1);
00546     rb_big_resize((VALUE)big, len + 1);
00547     digits = RBIGNUM_DIGITS(big);
00548 
00549     MEMCPY(digits, ptr, char, DEFAULT_SEED_LEN);
00550 
00551     /* set leading-zero-guard if need. */
00552     digits[len] =
00553 #if SIZEOF_INT32 / SIZEOF_BDIGITS > 1
00554         digits[len-2] <= 1 && digits[len-1] == 0
00555 #else
00556         digits[len-1] <= 1
00557 #endif
00558         ? 1 : 0;
00559 
00560     return rb_big_norm((VALUE)big);
00561 }
00562 
00563 /*
00564  * call-seq: Random.new_seed -> integer
00565  *
00566  * Returns an arbitrary seed value. This is used by Random.new
00567  * when no seed value is specified as an argument.
00568  *
00569  *   Random.new_seed  #=> 115032730400174366788466674494640623225
00570  */
00571 static VALUE
00572 random_seed(void)
00573 {
00574     unsigned int buf[DEFAULT_SEED_CNT];
00575     fill_random_seed(buf);
00576     return make_seed_value(buf);
00577 }
00578 
00579 /*
00580  * call-seq: prng.seed -> integer
00581  *
00582  * Returns the seed value used to initialize the generator. This may be used to
00583  * initialize another generator with the same state at a later time, causing it
00584  * to produce the same sequence of numbers.
00585  *
00586  *   prng1 = Random.new(1234)
00587  *   prng1.seed       #=> 1234
00588  *   prng1.rand(100)  #=> 47
00589  *
00590  *   prng2 = Random.new(prng1.seed)
00591  *   prng2.rand(100)  #=> 47
00592  */
00593 static VALUE
00594 random_get_seed(VALUE obj)
00595 {
00596     return get_rnd(obj)->seed;
00597 }
00598 
00599 /* :nodoc: */
00600 static VALUE
00601 random_copy(VALUE obj, VALUE orig)
00602 {
00603     rb_random_t *rnd1, *rnd2;
00604     struct MT *mt;
00605 
00606     if (!OBJ_INIT_COPY(obj, orig)) return obj;
00607 
00608     rnd1 = get_rnd(obj);
00609     rnd2 = get_rnd(orig);
00610     mt = &rnd1->mt;
00611 
00612     *rnd1 = *rnd2;
00613     mt->next = mt->state + numberof(mt->state) - mt->left + 1;
00614     return obj;
00615 }
00616 
00617 static VALUE
00618 mt_state(const struct MT *mt)
00619 {
00620     VALUE bigo = rb_big_new(sizeof(mt->state) / sizeof(BDIGIT), 1);
00621     BDIGIT *d = RBIGNUM_DIGITS(bigo);
00622     int i;
00623 
00624     for (i = 0; i < numberof(mt->state); ++i) {
00625         unsigned int x = mt->state[i];
00626 #if SIZEOF_BDIGITS < SIZEOF_INT32
00627         int j;
00628         for (j = 0; j < SIZEOF_INT32 / SIZEOF_BDIGITS; ++j) {
00629             *d++ = BIGLO(x);
00630             x = BIGDN(x);
00631         }
00632 #else
00633         *d++ = (BDIGIT)x;
00634 #endif
00635     }
00636     return rb_big_norm(bigo);
00637 }
00638 
00639 /* :nodoc: */
00640 static VALUE
00641 random_state(VALUE obj)
00642 {
00643     rb_random_t *rnd = get_rnd(obj);
00644     return mt_state(&rnd->mt);
00645 }
00646 
00647 /* :nodoc: */
00648 static VALUE
00649 random_s_state(VALUE klass)
00650 {
00651     return mt_state(&default_rand.mt);
00652 }
00653 
00654 /* :nodoc: */
00655 static VALUE
00656 random_left(VALUE obj)
00657 {
00658     rb_random_t *rnd = get_rnd(obj);
00659     return INT2FIX(rnd->mt.left);
00660 }
00661 
00662 /* :nodoc: */
00663 static VALUE
00664 random_s_left(VALUE klass)
00665 {
00666     return INT2FIX(default_rand.mt.left);
00667 }
00668 
00669 /* :nodoc: */
00670 static VALUE
00671 random_dump(VALUE obj)
00672 {
00673     rb_random_t *rnd = get_rnd(obj);
00674     VALUE dump = rb_ary_new2(3);
00675 
00676     rb_ary_push(dump, mt_state(&rnd->mt));
00677     rb_ary_push(dump, INT2FIX(rnd->mt.left));
00678     rb_ary_push(dump, rnd->seed);
00679 
00680     return dump;
00681 }
00682 
00683 /* :nodoc: */
00684 static VALUE
00685 random_load(VALUE obj, VALUE dump)
00686 {
00687     rb_random_t *rnd = get_rnd(obj);
00688     struct MT *mt = &rnd->mt;
00689     VALUE state, left = INT2FIX(1), seed = INT2FIX(0);
00690     VALUE *ary;
00691     unsigned long x;
00692 
00693     rb_check_copyable(obj, dump);
00694     Check_Type(dump, T_ARRAY);
00695     ary = RARRAY_PTR(dump);
00696     switch (RARRAY_LEN(dump)) {
00697       case 3:
00698         seed = ary[2];
00699       case 2:
00700         left = ary[1];
00701       case 1:
00702         state = ary[0];
00703         break;
00704       default:
00705         rb_raise(rb_eArgError, "wrong dump data");
00706     }
00707     memset(mt->state, 0, sizeof(mt->state));
00708     if (FIXNUM_P(state)) {
00709         x = FIX2ULONG(state);
00710         mt->state[0] = (unsigned int)x;
00711 #if SIZEOF_LONG / SIZEOF_INT >= 2
00712         mt->state[1] = (unsigned int)(x >> BITSPERDIG);
00713 #endif
00714 #if SIZEOF_LONG / SIZEOF_INT >= 3
00715         mt->state[2] = (unsigned int)(x >> 2 * BITSPERDIG);
00716 #endif
00717 #if SIZEOF_LONG / SIZEOF_INT >= 4
00718         mt->state[3] = (unsigned int)(x >> 3 * BITSPERDIG);
00719 #endif
00720     }
00721     else {
00722         BDIGIT *d;
00723         long len;
00724         Check_Type(state, T_BIGNUM);
00725         len = RBIGNUM_LEN(state);
00726         if (len > roomof(sizeof(mt->state), SIZEOF_BDIGITS)) {
00727             len = roomof(sizeof(mt->state), SIZEOF_BDIGITS);
00728         }
00729 #if SIZEOF_BDIGITS < SIZEOF_INT
00730         else if (len % DIGSPERINT) {
00731             d = RBIGNUM_DIGITS(state) + len;
00732 # if DIGSPERINT == 2
00733             --len;
00734             x = *--d;
00735 # else
00736             x = 0;
00737             do {
00738                 x = (x << BITSPERDIG) | *--d;
00739             } while (--len % DIGSPERINT);
00740 # endif
00741             mt->state[len / DIGSPERINT] = (unsigned int)x;
00742         }
00743 #endif
00744         if (len > 0) {
00745             d = BDIGITS(state) + len;
00746             do {
00747                 --len;
00748                 x = *--d;
00749 # if DIGSPERINT == 2
00750                 --len;
00751                 x = (x << BITSPERDIG) | *--d;
00752 # elif SIZEOF_BDIGITS < SIZEOF_INT
00753                 do {
00754                     x = (x << BITSPERDIG) | *--d;
00755                 } while (--len % DIGSPERINT);
00756 # endif
00757                 mt->state[len / DIGSPERINT] = (unsigned int)x;
00758             } while (len > 0);
00759         }
00760     }
00761     x = NUM2ULONG(left);
00762     if (x > numberof(mt->state)) {
00763         rb_raise(rb_eArgError, "wrong value");
00764     }
00765     mt->left = (unsigned int)x;
00766     mt->next = mt->state + numberof(mt->state) - x + 1;
00767     rnd->seed = rb_to_int(seed);
00768 
00769     return obj;
00770 }
00771 
00772 /*
00773  * call-seq:
00774  *   srand(number = Random.new_seed) -> old_seed
00775  *
00776  * Seeds the system pseudo-random number generator, Random::DEFAULT, with
00777  * +number+.  The previous seed value is returned.
00778  *
00779  * If +number+ is omitted, seeds the generator using a source of entropy
00780  * provided by the operating system, if available (/dev/urandom on Unix systems
00781  * or the RSA cryptographic provider on Windows), which is then combined with
00782  * the time, the process id, and a sequence number.
00783  *
00784  * srand may be used to ensure repeatable sequences of pseudo-random numbers
00785  * between different runs of the program. By setting the seed to a known value,
00786  * programs can be made deterministic during testing.
00787  *
00788  *   srand 1234               # => 268519324636777531569100071560086917274
00789  *   [ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
00790  *   [ rand(10), rand(1000) ] # => [4, 664]
00791  *   srand 1234               # => 1234
00792  *   [ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
00793  */
00794 
00795 static VALUE
00796 rb_f_srand(int argc, VALUE *argv, VALUE obj)
00797 {
00798     VALUE seed, old;
00799     rb_random_t *r = &default_rand;
00800 
00801     rb_secure(4);
00802     if (argc == 0) {
00803         seed = random_seed();
00804     }
00805     else {
00806         rb_scan_args(argc, argv, "01", &seed);
00807     }
00808     old = r->seed;
00809     r->seed = rand_init(&r->mt, seed);
00810 
00811     return old;
00812 }
00813 
00814 static unsigned long
00815 make_mask(unsigned long x)
00816 {
00817     x = x | x >> 1;
00818     x = x | x >> 2;
00819     x = x | x >> 4;
00820     x = x | x >> 8;
00821     x = x | x >> 16;
00822 #if 4 < SIZEOF_LONG
00823     x = x | x >> 32;
00824 #endif
00825     return x;
00826 }
00827 
00828 static unsigned long
00829 limited_rand(struct MT *mt, unsigned long limit)
00830 {
00831     /* mt must be initialized */
00832     int i;
00833     unsigned long val, mask;
00834 
00835     if (!limit) return 0;
00836     mask = make_mask(limit);
00837   retry:
00838     val = 0;
00839     for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
00840         if ((mask >> (i * 32)) & 0xffffffff) {
00841             val |= (unsigned long)genrand_int32(mt) << (i * 32);
00842             val &= mask;
00843             if (limit < val)
00844                 goto retry;
00845         }
00846     }
00847     return val;
00848 }
00849 
00850 static VALUE
00851 limited_big_rand(struct MT *mt, struct RBignum *limit)
00852 {
00853     /* mt must be initialized */
00854     unsigned long mask, lim, rnd;
00855     struct RBignum *val;
00856     long i, len;
00857     int boundary;
00858 
00859     len = (RBIGNUM_LEN(limit) * SIZEOF_BDIGITS + 3) / 4;
00860     val = (struct RBignum *)rb_big_clone((VALUE)limit);
00861     RBIGNUM_SET_SIGN(val, 1);
00862 #if SIZEOF_BDIGITS == 2
00863 # define BIG_GET32(big,i) \
00864     (RBIGNUM_DIGITS(big)[(i)*2] | \
00865      ((i)*2+1 < RBIGNUM_LEN(big) ? \
00866       (RBIGNUM_DIGITS(big)[(i)*2+1] << 16) : \
00867       0))
00868 # define BIG_SET32(big,i,d) \
00869     ((RBIGNUM_DIGITS(big)[(i)*2] = (d) & 0xffff), \
00870      ((i)*2+1 < RBIGNUM_LEN(big) ? \
00871       (RBIGNUM_DIGITS(big)[(i)*2+1] = (d) >> 16) : \
00872       0))
00873 #else
00874     /* SIZEOF_BDIGITS == 4 */
00875 # define BIG_GET32(big,i) (RBIGNUM_DIGITS(big)[(i)])
00876 # define BIG_SET32(big,i,d) (RBIGNUM_DIGITS(big)[(i)] = (d))
00877 #endif
00878   retry:
00879     mask = 0;
00880     boundary = 1;
00881     for (i = len-1; 0 <= i; i--) {
00882         lim = BIG_GET32(limit, i);
00883         mask = mask ? 0xffffffff : make_mask(lim);
00884         if (mask) {
00885             rnd = genrand_int32(mt) & mask;
00886             if (boundary) {
00887                 if (lim < rnd)
00888                     goto retry;
00889                 if (rnd < lim)
00890                     boundary = 0;
00891             }
00892         }
00893         else {
00894             rnd = 0;
00895         }
00896         BIG_SET32(val, i, (BDIGIT)rnd);
00897     }
00898     return rb_big_norm((VALUE)val);
00899 }
00900 
00901 /*
00902  * Returns random unsigned long value in [0, +limit+].
00903  *
00904  * Note that +limit+ is included, and the range of the argument and the
00905  * return value depends on environments.
00906  */
00907 unsigned long
00908 rb_genrand_ulong_limited(unsigned long limit)
00909 {
00910     return limited_rand(default_mt(), limit);
00911 }
00912 
00913 unsigned int
00914 rb_random_int32(VALUE obj)
00915 {
00916     rb_random_t *rnd = try_get_rnd(obj);
00917     if (!rnd) {
00918 #if SIZEOF_LONG * CHAR_BIT > 32
00919         VALUE lim = ULONG2NUM(0x100000000UL);
00920 #elif defined HAVE_LONG_LONG
00921         VALUE lim = ULL2NUM((LONG_LONG)0xffffffff+1);
00922 #else
00923         VALUE lim = rb_big_plus(ULONG2NUM(0xffffffff), INT2FIX(1));
00924 #endif
00925         return (unsigned int)NUM2ULONG(rb_funcall2(obj, id_rand, 1, &lim));
00926     }
00927     return genrand_int32(&rnd->mt);
00928 }
00929 
00930 double
00931 rb_random_real(VALUE obj)
00932 {
00933     rb_random_t *rnd = try_get_rnd(obj);
00934     if (!rnd) {
00935         VALUE v = rb_funcall2(obj, id_rand, 0, 0);
00936         double d = NUM2DBL(v);
00937         if (d < 0.0) {
00938             rb_raise(rb_eRangeError, "random number too small %g", d);
00939         }
00940         else if (d >= 1.0) {
00941             rb_raise(rb_eRangeError, "random number too big %g", d);
00942         }
00943         return d;
00944     }
00945     return genrand_real(&rnd->mt);
00946 }
00947 
00948 static inline VALUE
00949 ulong_to_num_plus_1(unsigned long n)
00950 {
00951 #if HAVE_LONG_LONG
00952     return ULL2NUM((LONG_LONG)n+1);
00953 #else
00954     if (n >= ULONG_MAX) {
00955         return rb_big_plus(ULONG2NUM(n), INT2FIX(1));
00956     }
00957     return ULONG2NUM(n+1);
00958 #endif
00959 }
00960 
00961 unsigned long
00962 rb_random_ulong_limited(VALUE obj, unsigned long limit)
00963 {
00964     rb_random_t *rnd = try_get_rnd(obj);
00965     if (!rnd) {
00966         extern int rb_num_negative_p(VALUE);
00967         VALUE lim = ulong_to_num_plus_1(limit);
00968         VALUE v = rb_funcall2(obj, id_rand, 1, &lim);
00969         unsigned long r = NUM2ULONG(v);
00970         if (rb_num_negative_p(v)) {
00971             rb_raise(rb_eRangeError, "random number too small %ld", r);
00972         }
00973         if (r > limit) {
00974             rb_raise(rb_eRangeError, "random number too big %ld", r);
00975         }
00976         return r;
00977     }
00978     return limited_rand(&rnd->mt, limit);
00979 }
00980 
00981 /*
00982  * call-seq: prng.bytes(size) -> a_string
00983  *
00984  * Returns a random binary string containing +size+ bytes.
00985  *
00986  *   random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO"
00987  *   random_string.size                   # => 10
00988  */
00989 static VALUE
00990 random_bytes(VALUE obj, VALUE len)
00991 {
00992     return rb_random_bytes(obj, NUM2LONG(rb_to_int(len)));
00993 }
00994 
00995 VALUE
00996 rb_random_bytes(VALUE obj, long n)
00997 {
00998     rb_random_t *rnd = try_get_rnd(obj);
00999     VALUE bytes;
01000     char *ptr;
01001     unsigned int r, i;
01002 
01003     if (!rnd) {
01004         VALUE len = LONG2NUM(n);
01005         return rb_funcall2(obj, id_bytes, 1, &len);
01006     }
01007     bytes = rb_str_new(0, n);
01008     ptr = RSTRING_PTR(bytes);
01009     for (; n >= SIZEOF_INT32; n -= SIZEOF_INT32) {
01010         r = genrand_int32(&rnd->mt);
01011         i = SIZEOF_INT32;
01012         do {
01013             *ptr++ = (char)r;
01014             r >>= CHAR_BIT;
01015         } while (--i);
01016     }
01017     if (n > 0) {
01018         r = genrand_int32(&rnd->mt);
01019         do {
01020             *ptr++ = (char)r;
01021             r >>= CHAR_BIT;
01022         } while (--n);
01023     }
01024     return bytes;
01025 }
01026 
01027 static VALUE
01028 range_values(VALUE vmax, VALUE *begp, VALUE *endp, int *exclp)
01029 {
01030     VALUE end, r;
01031 
01032     if (!rb_range_values(vmax, begp, &end, exclp)) return Qfalse;
01033     if (endp) *endp = end;
01034     if (!rb_respond_to(end, id_minus)) return Qfalse;
01035     r = rb_funcall2(end, id_minus, 1, begp);
01036     if (NIL_P(r)) return Qfalse;
01037     return r;
01038 }
01039 
01040 static VALUE
01041 rand_int(struct MT *mt, VALUE vmax, int restrictive)
01042 {
01043     /* mt must be initialized */
01044     long max;
01045     unsigned long r;
01046 
01047     if (FIXNUM_P(vmax)) {
01048         max = FIX2LONG(vmax);
01049         if (!max) return Qnil;
01050         if (max < 0) {
01051             if (restrictive) return Qnil;
01052             max = -max;
01053         }
01054         r = limited_rand(mt, (unsigned long)max - 1);
01055         return ULONG2NUM(r);
01056     }
01057     else {
01058         VALUE ret;
01059         if (rb_bigzero_p(vmax)) return Qnil;
01060         if (!RBIGNUM_SIGN(vmax)) {
01061             if (restrictive) return Qnil;
01062             vmax = rb_big_clone(vmax);
01063             RBIGNUM_SET_SIGN(vmax, 1);
01064         }
01065         vmax = rb_big_minus(vmax, INT2FIX(1));
01066         if (FIXNUM_P(vmax)) {
01067             max = FIX2LONG(vmax);
01068             if (max == -1) return Qnil;
01069             r = limited_rand(mt, max);
01070             return LONG2NUM(r);
01071         }
01072         ret = limited_big_rand(mt, RBIGNUM(vmax));
01073         RB_GC_GUARD(vmax);
01074         return ret;
01075     }
01076 }
01077 
01078 static inline double
01079 float_value(VALUE v)
01080 {
01081     double x = RFLOAT_VALUE(v);
01082     if (isinf(x) || isnan(x)) {
01083         VALUE error = INT2FIX(EDOM);
01084         rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
01085     }
01086     return x;
01087 }
01088 
01089 static inline VALUE
01090 rand_range(struct MT* mt, VALUE range)
01091 {
01092     VALUE beg = Qundef, end = Qundef, vmax, v;
01093     int excl = 0;
01094 
01095     if ((v = vmax = range_values(range, &beg, &end, &excl)) == Qfalse)
01096         return Qfalse;
01097     if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
01098         long max;
01099         vmax = v;
01100         v = Qnil;
01101         if (FIXNUM_P(vmax)) {
01102           fixnum:
01103             if ((max = FIX2LONG(vmax) - excl) >= 0) {
01104                 unsigned long r = limited_rand(mt, (unsigned long)max);
01105                 v = ULONG2NUM(r);
01106             }
01107         }
01108         else if (BUILTIN_TYPE(vmax) == T_BIGNUM && RBIGNUM_SIGN(vmax) && !rb_bigzero_p(vmax)) {
01109             vmax = excl ? rb_big_minus(vmax, INT2FIX(1)) : rb_big_norm(vmax);
01110             if (FIXNUM_P(vmax)) {
01111                 excl = 0;
01112                 goto fixnum;
01113             }
01114             v = limited_big_rand(mt, RBIGNUM(vmax));
01115         }
01116     }
01117     else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
01118         int scale = 1;
01119         double max = RFLOAT_VALUE(v), mid = 0.5, r;
01120         if (isinf(max)) {
01121             double min = float_value(rb_to_float(beg)) / 2.0;
01122             max = float_value(rb_to_float(end)) / 2.0;
01123             scale = 2;
01124             mid = max + min;
01125             max -= min;
01126         }
01127         else {
01128             float_value(v);
01129         }
01130         v = Qnil;
01131         if (max > 0.0) {
01132             if (excl) {
01133                 r = genrand_real(mt);
01134             }
01135             else {
01136                 r = genrand_real2(mt);
01137             }
01138             if (scale > 1) {
01139                 return rb_float_new(+(+(+(r - 0.5) * max) * scale) + mid);
01140             }
01141             v = rb_float_new(r * max);
01142         }
01143         else if (max == 0.0 && !excl) {
01144             v = rb_float_new(0.0);
01145         }
01146     }
01147 
01148     if (FIXNUM_P(beg) && FIXNUM_P(v)) {
01149         long x = FIX2LONG(beg) + FIX2LONG(v);
01150         return LONG2NUM(x);
01151     }
01152     switch (TYPE(v)) {
01153       case T_NIL:
01154         break;
01155       case T_BIGNUM:
01156         return rb_big_plus(v, beg);
01157       case T_FLOAT: {
01158         VALUE f = rb_check_to_float(beg);
01159         if (!NIL_P(f)) {
01160             return DBL2NUM(RFLOAT_VALUE(v) + RFLOAT_VALUE(f));
01161         }
01162       }
01163       default:
01164         return rb_funcall2(beg, id_plus, 1, &v);
01165     }
01166 
01167     return v;
01168 }
01169 
01170 static VALUE rand_random(int argc, VALUE *argv, rb_random_t *rnd);
01171 
01172 /*
01173  * call-seq:
01174  *   prng.rand -> float
01175  *   prng.rand(max) -> number
01176  *
01177  * When +max+ is an Integer, +rand+ returns a random integer greater than
01178  * or equal to zero and less than +max+. Unlike Kernel.rand, when +max+
01179  * is a negative integer or zero, +rand+ raises an ArgumentError.
01180  *
01181  *   prng = Random.new
01182  *   prng.rand(100)       # => 42
01183  *
01184  * When +max+ is a Float, +rand+ returns a random floating point number
01185  * between 0.0 and +max+, including 0.0 and excluding +max+.
01186  *
01187  *   prng.rand(1.5)       # => 1.4600282860034115
01188  *
01189  * When +max+ is a Range, +rand+ returns a random number where
01190  * range.member?(number) == true.
01191  *
01192  *   prng.rand(5..9)      # => one of [5, 6, 7, 8, 9]
01193  *   prng.rand(5...9)     # => one of [5, 6, 7, 8]
01194  *   prng.rand(5.0..9.0)  # => between 5.0 and 9.0, including 9.0
01195  *   prng.rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
01196  *
01197  * Both the beginning and ending values of the range must respond to subtract
01198  * (<tt>-</tt>) and add (<tt>+</tt>)methods, or rand will raise an
01199  * ArgumentError.
01200  */
01201 static VALUE
01202 random_rand(int argc, VALUE *argv, VALUE obj)
01203 {
01204     return rand_random(argc, argv, get_rnd(obj));
01205 }
01206 
01207 static VALUE
01208 rand_random(int argc, VALUE *argv, rb_random_t *rnd)
01209 {
01210     VALUE vmax, v;
01211 
01212     if (argc == 0) {
01213         return rb_float_new(genrand_real(&rnd->mt));
01214     }
01215     else {
01216         rb_check_arity(argc, 0, 1);
01217     }
01218     vmax = argv[0];
01219     if (NIL_P(vmax)) {
01220         v = Qnil;
01221     }
01222     else if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
01223         v = rand_int(&rnd->mt, v, 1);
01224     }
01225     else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
01226         double max = float_value(v);
01227         if (max > 0.0)
01228             v = rb_float_new(max * genrand_real(&rnd->mt));
01229         else
01230             v = Qnil;
01231     }
01232     else if ((v = rand_range(&rnd->mt, vmax)) != Qfalse) {
01233         /* nothing to do */
01234     }
01235     else {
01236         v = Qnil;
01237         (void)NUM2LONG(vmax);
01238     }
01239     if (NIL_P(v)) {
01240         VALUE mesg = rb_str_new_cstr("invalid argument - ");
01241         rb_str_append(mesg, rb_obj_as_string(argv[0]));
01242         rb_exc_raise(rb_exc_new3(rb_eArgError, mesg));
01243     }
01244 
01245     return v;
01246 }
01247 
01248 /*
01249  * call-seq:
01250  *   prng1 == prng2 -> true or false
01251  *
01252  * Returns true if the two generators have the same internal state, otherwise
01253  * false.  Equivalent generators will return the same sequence of
01254  * pseudo-random numbers.  Two generators will generally have the same state
01255  * only if they were initialized with the same seed
01256  *
01257  *   Random.new == Random.new             # => false
01258  *   Random.new(1234) == Random.new(1234) # => true
01259  *
01260  * and have the same invocation history.
01261  *
01262  *   prng1 = Random.new(1234)
01263  *   prng2 = Random.new(1234)
01264  *   prng1 == prng2 # => true
01265  *
01266  *   prng1.rand     # => 0.1915194503788923
01267  *   prng1 == prng2 # => false
01268  *
01269  *   prng2.rand     # => 0.1915194503788923
01270  *   prng1 == prng2 # => true
01271  */
01272 static VALUE
01273 random_equal(VALUE self, VALUE other)
01274 {
01275     rb_random_t *r1, *r2;
01276     if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
01277     r1 = get_rnd(self);
01278     r2 = get_rnd(other);
01279     if (!RTEST(rb_funcall2(r1->seed, rb_intern("=="), 1, &r2->seed))) return Qfalse;
01280     if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
01281     if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
01282     if (r1->mt.left != r2->mt.left) return Qfalse;
01283     return Qtrue;
01284 }
01285 
01286 /*
01287  * call-seq:
01288  *   rand(max=0)    -> number
01289  *
01290  * If called without an argument, or if <tt>max.to_i.abs == 0</tt>, rand
01291  * returns a pseudo-random floating point number between 0.0 and 1.0,
01292  * including 0.0 and excluding 1.0.
01293  *
01294  *   rand        #=> 0.2725926052826416
01295  *
01296  * When +max.abs+ is greater than or equal to 1, +rand+ returns a pseudo-random
01297  * integer greater than or equal to 0 and less than +max.to_i.abs+.
01298  *
01299  *   rand(100)   #=> 12
01300  *
01301  * When +max+ is a Range, +rand+ returns a random number where
01302  * range.member?(number) == true.
01303  *
01304  * Negative or floating point values for +max+ are allowed, but may give
01305  * surprising results.
01306  *
01307  *   rand(-100) # => 87
01308  *   rand(-0.5) # => 0.8130921818028143
01309  *   rand(1.9)  # equivalent to rand(1), which is always 0
01310  *
01311  * Kernel.srand may be used to ensure that sequences of random numbers are
01312  * reproducible between different runs of a program.
01313  *
01314  * See also Random.rand.
01315  */
01316 
01317 static VALUE
01318 rb_f_rand(int argc, VALUE *argv, VALUE obj)
01319 {
01320     VALUE v, vmax, r;
01321     struct MT *mt = default_mt();
01322 
01323     if (argc == 0) goto zero_arg;
01324     rb_scan_args(argc, argv, "01", &vmax);
01325     if (NIL_P(vmax)) goto zero_arg;
01326     if ((v = rand_range(mt, vmax)) != Qfalse) {
01327         return v;
01328     }
01329     vmax = rb_to_int(vmax);
01330     if (vmax == INT2FIX(0) || NIL_P(r = rand_int(mt, vmax, 0))) {
01331       zero_arg:
01332         return DBL2NUM(genrand_real(mt));
01333     }
01334     return r;
01335 }
01336 
01337 /*
01338  * call-seq:
01339  *   Random.rand -> float
01340  *   Random.rand(max) -> number
01341  *
01342  * Alias of Random::DEFAULT.rand.
01343  */
01344 
01345 static VALUE
01346 random_s_rand(int argc, VALUE *argv, VALUE obj)
01347 {
01348     return rand_random(argc, argv, rand_start(&default_rand));
01349 }
01350 
01351 #define SIP_HASH_STREAMING 0
01352 #define sip_hash24 ruby_sip_hash24
01353 #if !defined _WIN32 && !defined BYTE_ORDER
01354 # ifdef WORDS_BIGENDIAN
01355 #   define BYTE_ORDER BIG_ENDIAN
01356 # else
01357 #   define BYTE_ORDER LITTLE_ENDIAN
01358 # endif
01359 # ifndef LITTLE_ENDIAN
01360 #   define LITTLE_ENDIAN 1234
01361 # endif
01362 # ifndef BIG_ENDIAN
01363 #   define BIG_ENDIAN    4321
01364 # endif
01365 #endif
01366 #include "siphash.c"
01367 
01368 static st_index_t hashseed;
01369 static union {
01370     uint8_t key[16];
01371     uint32_t u32[(16 * sizeof(uint8_t) - 1) / sizeof(uint32_t)];
01372 } sipseed;
01373 
01374 static VALUE
01375 init_randomseed(struct MT *mt, unsigned int initial[DEFAULT_SEED_CNT])
01376 {
01377     VALUE seed;
01378     fill_random_seed(initial);
01379     init_by_array(mt, initial, DEFAULT_SEED_CNT);
01380     seed = make_seed_value(initial);
01381     memset(initial, 0, DEFAULT_SEED_LEN);
01382     return seed;
01383 }
01384 
01385 void
01386 Init_RandomSeed(void)
01387 {
01388     rb_random_t *r = &default_rand;
01389     unsigned int initial[DEFAULT_SEED_CNT];
01390     struct MT *mt = &r->mt;
01391     VALUE seed = init_randomseed(mt, initial);
01392     int i;
01393 
01394     hashseed = genrand_int32(mt);
01395 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8
01396     hashseed <<= 32;
01397     hashseed |= genrand_int32(mt);
01398 #endif
01399 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
01400     hashseed <<= 32;
01401     hashseed |= genrand_int32(mt);
01402 #endif
01403 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 12*8
01404     hashseed <<= 32;
01405     hashseed |= genrand_int32(mt);
01406 #endif
01407 
01408     for (i = 0; i < numberof(sipseed.u32); ++i)
01409         sipseed.u32[i] = genrand_int32(mt);
01410 
01411     rb_global_variable(&r->seed);
01412     r->seed = seed;
01413 }
01414 
01415 st_index_t
01416 rb_hash_start(st_index_t h)
01417 {
01418     return st_hash_start(hashseed + h);
01419 }
01420 
01421 st_index_t
01422 rb_memhash(const void *ptr, long len)
01423 {
01424     sip_uint64_t h = sip_hash24(sipseed.key, ptr, len);
01425 #ifdef HAVE_UINT64_T
01426     return (st_index_t)h;
01427 #else
01428     return (st_index_t)(h.u32[0] ^ h.u32[1]);
01429 #endif
01430 }
01431 
01432 static void
01433 Init_RandomSeed2(void)
01434 {
01435     VALUE seed = default_rand.seed;
01436 
01437     if (RB_TYPE_P(seed, T_BIGNUM)) {
01438         RBASIC(seed)->klass = rb_cBignum;
01439     }
01440 }
01441 
01442 void
01443 rb_reset_random_seed(void)
01444 {
01445     rb_random_t *r = &default_rand;
01446     uninit_genrand(&r->mt);
01447     r->seed = INT2FIX(0);
01448 }
01449 
01450 /*
01451  * Document-class: Random
01452  *
01453  * Random provides an interface to Ruby's pseudo-random number generator, or
01454  * PRNG.  The PRNG produces a deterministic sequence of bits which approximate
01455  * true randomness. The sequence may be represented by integers, floats, or
01456  * binary strings.
01457  *
01458  * The generator may be initialized with either a system-generated or
01459  * user-supplied seed value by using Random.srand.
01460  *
01461  * The class method Random.rand provides the base functionality of Kernel.rand
01462  * along with better handling of floating point values. These are both
01463  * interfaces to Random::DEFAULT, the Ruby system PRNG.
01464  *
01465  * Random.new will create a new PRNG with a state independent of
01466  * Random::DEFAULT, allowing multiple generators with different seed values or
01467  * sequence positions to exist simultaneously. Random objects can be
01468  * marshaled, allowing sequences to be saved and resumed.
01469  *
01470  * PRNGs are currently implemented as a modified Mersenne Twister with a period
01471  * of 2**19937-1.
01472  */
01473 
01474 void
01475 Init_Random(void)
01476 {
01477     Init_RandomSeed2();
01478     rb_define_global_function("srand", rb_f_srand, -1);
01479     rb_define_global_function("rand", rb_f_rand, -1);
01480 
01481     rb_cRandom = rb_define_class("Random", rb_cObject);
01482     rb_define_alloc_func(rb_cRandom, random_alloc);
01483     rb_define_method(rb_cRandom, "initialize", random_init, -1);
01484     rb_define_method(rb_cRandom, "rand", random_rand, -1);
01485     rb_define_method(rb_cRandom, "bytes", random_bytes, 1);
01486     rb_define_method(rb_cRandom, "seed", random_get_seed, 0);
01487     rb_define_method(rb_cRandom, "initialize_copy", random_copy, 1);
01488     rb_define_private_method(rb_cRandom, "marshal_dump", random_dump, 0);
01489     rb_define_private_method(rb_cRandom, "marshal_load", random_load, 1);
01490     rb_define_private_method(rb_cRandom, "state", random_state, 0);
01491     rb_define_private_method(rb_cRandom, "left", random_left, 0);
01492     rb_define_method(rb_cRandom, "==", random_equal, 1);
01493 
01494     {
01495         VALUE rand_default = TypedData_Wrap_Struct(rb_cRandom, &random_data_type, &default_rand);
01496         rb_gc_register_mark_object(rand_default);
01497         rb_define_const(rb_cRandom, "DEFAULT", rand_default);
01498     }
01499 
01500     rb_define_singleton_method(rb_cRandom, "srand", rb_f_srand, -1);
01501     rb_define_singleton_method(rb_cRandom, "rand", random_s_rand, -1);
01502     rb_define_singleton_method(rb_cRandom, "new_seed", random_seed, 0);
01503     rb_define_private_method(CLASS_OF(rb_cRandom), "state", random_s_state, 0);
01504     rb_define_private_method(CLASS_OF(rb_cRandom), "left", random_s_left, 0);
01505 
01506     id_rand = rb_intern("rand");
01507     id_bytes = rb_intern("bytes");
01508 }
01509