Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

random.c
Go to the documentation of this file.
1 /**********************************************************************
2
3 random.c -
4
5 $Author: nagachika $
6 created at: Fri Dec 24 16:39:21 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10 **********************************************************************/
11
12 /*
13 This is based on trimmed version of MT19937. To get the original version,
14 contact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.
15
16 The original copyright notice follows.
17
18 A C-program for MT19937, with initialization improved 2002/2/10.
19 Coded by Takuji Nishimura and Makoto Matsumoto.
20 This is a faster version by taking Shawn Cokus's optimization,
21 Matthe Bellew's simplification, Isaku Wada's real version.
22
23 Before using, initialize the state by using init_genrand(mt, seed)
24 or init_by_array(mt, init_key, key_length).
25
26 Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
27 All rights reserved.
28
29 Redistribution and use in source and binary forms, with or without
30 modification, are permitted provided that the following conditions
31 are met:
32
33 1. Redistributions of source code must retain the above copyright
34 notice, this list of conditions and the following disclaimer.
35
36 2. Redistributions in binary form must reproduce the above copyright
37 notice, this list of conditions and the following disclaimer in the
38 documentation and/or other materials provided with the distribution.
39
40 3. The names of its contributors may not be used to endorse or promote
41 products derived from this software without specific prior written
42 permission.
43
44 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
46 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
47 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
48 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
49 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
50 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
51 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
52 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
53 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
54 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55
56
57 Any feedback is very welcome.
58 http://www.math.keio.ac.jp/matumoto/emt.html
59 email: matumoto@math.keio.ac.jp
60 */
61
62 #include "ruby/ruby.h"
63
64 #include <limits.h>
65 #ifdef HAVE_UNISTD_H
66 #include <unistd.h>
67 #endif
68 #include <time.h>
69 #include <sys/types.h>
70 #include <sys/stat.h>
71 #ifdef HAVE_FCNTL_H
72 #include <fcntl.h>
73 #endif
74 #include <math.h>
75 #include <errno.h>
76 #if defined(HAVE_SYS_TIME_H)
77 #include <sys/time.h>
78 #endif
79
80 #ifdef _WIN32
81 # if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0400
82 # undef _WIN32_WINNT
83 # define _WIN32_WINNT 0x400
84 # undef __WINCRYPT_H__
85 # endif
86 #include <wincrypt.h>
87 #endif
88
89 typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
90
91 /* Period parameters */
92 #define N 624
93 #define M 397
94 #define MATRIX_A 0x9908b0dfU /* constant vector a */
95 #define UMASK 0x80000000U /* most significant w-r bits */
96 #define LMASK 0x7fffffffU /* least significant r bits */
97 #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
98 #define TWIST(u,v) ((MIXBITS((u),(v)) >> 1) ^ ((v)&1U ? MATRIX_A : 0U))
99
100 enum {MT_MAX_STATE = N};
101
102 struct MT {
103 /* assume int is enough to store 32bits */
104 unsigned int state[N]; /* the array for the state vector */
105 unsigned int *next;
106 int left;
107 };
108
109 #define genrand_initialized(mt) ((mt)->next != 0)
110 #define uninit_genrand(mt) ((mt)->next = 0)
111
112 /* initializes state[N] with a seed */
113 static void
114 init_genrand(struct MT *mt, unsigned int s)
115 {
116 int j;
117 mt->state[0] = s & 0xffffffffU;
118 for (j=1; j<N; j++) {
119 mt->state[j] = (1812433253U * (mt->state[j-1] ^ (mt->state[j-1] >> 30)) + j);
120 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
121 /* In the previous versions, MSBs of the seed affect */
122 /* only MSBs of the array state[]. */
123 /* 2002/01/09 modified by Makoto Matsumoto */
124 mt->state[j] &= 0xffffffff; /* for >32 bit machines */
125 }
126 mt->left = 1;
127 mt->next = mt->state + N;
128 }
129
130 /* initialize by an array with array-length */
131 /* init_key is the array for initializing keys */
132 /* key_length is its length */
133 /* slight change for C++, 2004/2/26 */
134 static void
135 init_by_array(struct MT *mt, unsigned int init_key[], int key_length)
136 {
137 int i, j, k;
138 init_genrand(mt, 19650218U);
139 i=1; j=0;
140 k = (N>key_length ? N : key_length);
141 for (; k; k--) {
142 mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1664525U))
143 + init_key[j] + j; /* non linear */
144 mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
145 i++; j++;
146 if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
147 if (j>=key_length) j=0;
148 }
149 for (k=N-1; k; k--) {
150 mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1566083941U))
151 - i; /* non linear */
152 mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
153 i++;
154 if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
155 }
156
157 mt->state[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
158 }
159
160 static void
161 next_state(struct MT *mt)
162 {
163 unsigned int *p = mt->state;
164 int j;
165
166 mt->left = N;
167 mt->next = mt->state;
168
169 for (j=N-M+1; --j; p++)
170 *p = p[M] ^ TWIST(p[0], p[1]);
171
172 for (j=M; --j; p++)
173 *p = p[M-N] ^ TWIST(p[0], p[1]);
174
175 *p = p[M-N] ^ TWIST(p[0], mt->state[0]);
176 }
177
178 /* generates a random number on [0,0xffffffff]-interval */
179 static unsigned int
180 genrand_int32(struct MT *mt)
181 {
182 /* mt must be initialized */
183 unsigned int y;
184
185 if (--mt->left <= 0) next_state(mt);
186 y = *mt->next++;
187
188 /* Tempering */
189 y ^= (y >> 11);
190 y ^= (y << 7) & 0x9d2c5680;
191 y ^= (y << 15) & 0xefc60000;
192 y ^= (y >> 18);
193
194 return y;
195 }
196
197 /* generates a random number on [0,1) with 53-bit resolution*/
198 static double
199 genrand_real(struct MT *mt)
200 {
201 /* mt must be initialized */
202 unsigned int a = genrand_int32(mt)>>5, b = genrand_int32(mt)>>6;
203 return(a*67108864.0+b)*(1.0/9007199254740992.0);
204 }
205
206 /* generates a random number on [0,1] with 53-bit resolution*/
207 static double int_pair_to_real_inclusive(unsigned int a, unsigned int b);
208 static double
209 genrand_real2(struct MT *mt)
210 {
211 /* mt must be initialized */
212 unsigned int a = genrand_int32(mt), b = genrand_int32(mt);
213 return int_pair_to_real_inclusive(a, b);
214 }
215
216 /* These real versions are due to Isaku Wada, 2002/01/09 added */
217
218 #undef N
219 #undef M
220
221 typedef struct {
222 VALUE seed;
223 struct MT mt;
224 } rb_random_t;
225
226 #define DEFAULT_SEED_CNT 4
227
228 static rb_random_t default_rand;
229
230 static VALUE rand_init(struct MT *mt, VALUE vseed);
231 static VALUE random_seed(void);
232
233 static rb_random_t *
234 rand_start(rb_random_t *r)
235 {
236 struct MT *mt = &r->mt;
237 if (!genrand_initialized(mt)) {
238 r->seed = rand_init(mt, random_seed());
239 }
240 return r;
241 }
242
243 static struct MT *
244 default_mt(void)
245 {
246 return &rand_start(&default_rand)->mt;
247 }
248
249 unsigned int
250 rb_genrand_int32(void)
251 {
252 struct MT *mt = default_mt();
253 return genrand_int32(mt);
254 }
255
256 double
257 rb_genrand_real(void)
258 {
259 struct MT *mt = default_mt();
260 return genrand_real(mt);
261 }
262
263 #define BDIGITS(x) (RBIGNUM_DIGITS(x))
264 #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
265 #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
266 #define DIGSPERINT (SIZEOF_INT/SIZEOF_BDIGITS)
267 #define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)
268 #define BIGDN(x) RSHIFT((x),BITSPERDIG)
269 #define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))
270 #define BDIGMAX ((BDIGIT)-1)
271
272 #define roomof(n, m) (int)(((n)+(m)-1) / (m))
273 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
274 #define SIZEOF_INT32 (31/CHAR_BIT + 1)
275
276 static double
277 int_pair_to_real_inclusive(unsigned int a, unsigned int b)
278 {
279 VALUE x = rb_big_new(roomof(64, BITSPERDIG), 1);
280 VALUE m = rb_big_new(roomof(53, BITSPERDIG), 1);
281 BDIGIT *xd = BDIGITS(x);
282 int i = 0;
283 double r;
284
285 xd[i++] = (BDIGIT)b;
286 #if BITSPERDIG < 32
287 xd[i++] = (BDIGIT)(b >> BITSPERDIG);
288 #endif
289 xd[i++] = (BDIGIT)a;
290 #if BITSPERDIG < 32
291 xd[i++] = (BDIGIT)(a >> BITSPERDIG);
292 #endif
293 xd = BDIGITS(m);
294 #if BITSPERDIG < 53
295 MEMZERO(xd, BDIGIT, roomof(53, BITSPERDIG) - 1);
296 #endif
297 xd[53 / BITSPERDIG] = 1 << 53 % BITSPERDIG;
298 xd[0] |= 1;
299 x = rb_big_mul(x, m);
300 if (FIXNUM_P(x)) {
301 #if CHAR_BIT * SIZEOF_LONG > 64
302 r = (double)(FIX2ULONG(x) >> 64);
303 #else
304 return 0.0;
305 #endif
306 }
307 else {
308 #if 64 % BITSPERDIG == 0
309 long len = RBIGNUM_LEN(x);
310 xd = BDIGITS(x);
311 MEMMOVE(xd, xd + 64 / BITSPERDIG, BDIGIT, len - 64 / BITSPERDIG);
312 MEMZERO(xd + len - 64 / BITSPERDIG, BDIGIT, 64 / BITSPERDIG);
313 r = rb_big2dbl(x);
314 #else
315 x = rb_big_rshift(x, INT2FIX(64));
316 if (FIXNUM_P(x)) {
317 r = (double)FIX2ULONG(x);
318 }
319 else {
320 r = rb_big2dbl(x);
321 }
322 #endif
323 }
324 return ldexp(r, -53);
325 }
326
327 VALUE rb_cRandom;
328 #define id_minus '-'
329 #define id_plus '+'
330 static ID id_rand, id_bytes;
331
332 /* :nodoc: */
333 static void
334 random_mark(void *ptr)
335 {
336 rb_gc_mark(((rb_random_t *)ptr)->seed);
337 }
338
339 static void
340 random_free(void *ptr)
341 {
342 if (ptr != &default_rand)
343 xfree(ptr);
344 }
345
346 static size_t
347 random_memsize(const void *ptr)
348 {
349 return ptr ? sizeof(rb_random_t) : 0;
350 }
351
352 static const rb_data_type_t random_data_type = {
353 "random",
354 {
355 random_mark,
356 random_free,
357 random_memsize,
358 },
359 };
360
361 static rb_random_t *
362 get_rnd(VALUE obj)
363 {
364 rb_random_t *ptr;
365 TypedData_Get_Struct(obj, rb_random_t, &random_data_type, ptr);
366 return ptr;
367 }
368
369 static rb_random_t *
370 try_get_rnd(VALUE obj)
371 {
372 if (obj == rb_cRandom) {
373 return rand_start(&default_rand);
374 }
375 if (!rb_typeddata_is_kind_of(obj, &random_data_type)) return NULL;
376 return DATA_PTR(obj);
377 }
378
379 /* :nodoc: */
380 static VALUE
381 random_alloc(VALUE klass)
382 {
383 rb_random_t *rnd;
384 VALUE obj = TypedData_Make_Struct(klass, rb_random_t, &random_data_type, rnd);
385 rnd->seed = INT2FIX(0);
386 return obj;
387 }
388
389 static VALUE
390 rand_init(struct MT *mt, VALUE vseed)
391 {
392 volatile VALUE seed;
393 long blen = 0;
394 long fixnum_seed;
395 int i, j, len;
396 unsigned int buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;
397
398 seed = rb_to_int(vseed);
399 switch (TYPE(seed)) {
400 case T_FIXNUM:
401 len = 1;
402 fixnum_seed = FIX2LONG(seed);
403 if (fixnum_seed < 0)
404 fixnum_seed = -fixnum_seed;
405 buf[0] = (unsigned int)(fixnum_seed & 0xffffffff);
406 #if SIZEOF_LONG > SIZEOF_INT32
407 if ((long)(int32_t)fixnum_seed != fixnum_seed) {
408 if ((buf[1] = (unsigned int)(fixnum_seed >> 32)) != 0) ++len;
409 }
410 #endif
411 break;
412 case T_BIGNUM:
413 blen = RBIGNUM_LEN(seed);
414 if (blen == 0) {
415 len = 1;
416 }
417 else {
418 if (blen > MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS)
419 blen = MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS;
420 len = roomof((int)blen * SIZEOF_BDIGITS, SIZEOF_INT32);
421 }
422 /* allocate ints for init_by_array */
423 if (len > numberof(buf0)) buf = ALLOC_N(unsigned int, len);
424 memset(buf, 0, len * sizeof(*buf));
425 len = 0;
426 for (i = (int)(blen-1); 0 <= i; i--) {
427 j = i * SIZEOF_BDIGITS / SIZEOF_INT32;
428 #if SIZEOF_BDIGITS < SIZEOF_INT32
429 buf[j] <<= BITSPERDIG;
430 #endif
431 buf[j] |= RBIGNUM_DIGITS(seed)[i];
432 if (!len && buf[j]) len = j;
433 }
434 ++len;
435 break;
436 default:
437 rb_raise(rb_eTypeError, "failed to convert %s into Integer",
438 rb_obj_classname(vseed));
439 }
440 if (len <= 1) {
441 init_genrand(mt, buf[0]);
442 }
443 else {
444 if (buf[len-1] == 1) /* remove leading-zero-guard */
445 len--;
446 init_by_array(mt, buf, len);
447 }
448 if (buf != buf0) xfree(buf);
449 return seed;
450 }
451
452 /*
453 * call-seq:
454 * Random.new(seed = Random.new_seed) -> prng
455 *
456 * Creates a new PRNG using +seed+ to set the initial state. If +seed+ is
457 * omitted, the generator is initialized with Random.new_seed.
458 *
459 * See Random.srand for more information on the use of seed values.
460 */
461 static VALUE
462 random_init(int argc, VALUE *argv, VALUE obj)
463 {
464 VALUE vseed;
465 rb_random_t *rnd = get_rnd(obj);
466
467 if (argc == 0) {
468 rb_check_frozen(obj);
469 vseed = random_seed();
470 }
471 else {
472 rb_scan_args(argc, argv, "01", &vseed);
473 rb_check_copyable(obj, vseed);
474 }
475 rnd->seed = rand_init(&rnd->mt, vseed);
476 return obj;
477 }
478
479 #define DEFAULT_SEED_LEN (DEFAULT_SEED_CNT * (int)sizeof(int))
480
481 #if defined(S_ISCHR) && !defined(DOSISH)
482 # define USE_DEV_URANDOM 1
483 #else
484 # define USE_DEV_URANDOM 0
485 #endif
486
487 static void
488 fill_random_seed(unsigned int seed[DEFAULT_SEED_CNT])
489 {
490 static int n = 0;
491 struct timeval tv;
492 #if USE_DEV_URANDOM
493 int fd;
494 struct stat statbuf;
495 #elif defined(_WIN32)
496 HCRYPTPROV prov;
497 #endif
498
499 memset(seed, 0, DEFAULT_SEED_LEN);
500
501 #if USE_DEV_URANDOM
502 if ((fd = rb_cloexec_open("/dev/urandom", O_RDONLY
503 #ifdef O_NONBLOCK
504 |O_NONBLOCK
505 #endif
506 #ifdef O_NOCTTY
507 |O_NOCTTY
508 #endif
509 , 0)) >= 0) {
510 rb_update_max_fd(fd);
511 if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
512 if (read(fd, seed, DEFAULT_SEED_LEN) < DEFAULT_SEED_LEN) {
513 /* abandon */;
514 }
515 }
516 close(fd);
517 }
518 #elif defined(_WIN32)
519 if (CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
520 CryptGenRandom(prov, DEFAULT_SEED_LEN, (void *)seed);
521 CryptReleaseContext(prov, 0);
522 }
523 #endif
524
525 gettimeofday(&tv, 0);
526 seed[0] ^= tv.tv_usec;
527 seed[1] ^= (unsigned int)tv.tv_sec;
528 #if SIZEOF_TIME_T > SIZEOF_INT
529 seed[0] ^= (unsigned int)((time_t)tv.tv_sec >> SIZEOF_INT * CHAR_BIT);
530 #endif
531 seed[2] ^= getpid() ^ (n++ << 16);
532 seed[3] ^= (unsigned int)(VALUE)&seed;
533 #if SIZEOF_VOIDP > SIZEOF_INT
534 seed[2] ^= (unsigned int)((VALUE)&seed >> SIZEOF_INT * CHAR_BIT);
535 #endif
536 }
537
538 static VALUE
539 make_seed_value(const void *ptr)
540 {
541 const long len = DEFAULT_SEED_LEN/SIZEOF_BDIGITS;
542 BDIGIT *digits;
543 NEWOBJ_OF(big, struct RBignum, rb_cBignum, T_BIGNUM);
544
545 RBIGNUM_SET_SIGN(big, 1);
546 rb_big_resize((VALUE)big, len + 1);
547 digits = RBIGNUM_DIGITS(big);
548
549 MEMCPY(digits, ptr, char, DEFAULT_SEED_LEN);
550
551 /* set leading-zero-guard if need. */
552 digits[len] =
553 #if SIZEOF_INT32 / SIZEOF_BDIGITS > 1
554 digits[len-2] <= 1 && digits[len-1] == 0
555 #else
556 digits[len-1] <= 1
557 #endif
558 ? 1 : 0;
559
560 return rb_big_norm((VALUE)big);
561 }
562
563 /*
564 * call-seq: Random.new_seed -> integer
565 *
566 * Returns an arbitrary seed value. This is used by Random.new
567 * when no seed value is specified as an argument.
568 *
569 * Random.new_seed #=> 115032730400174366788466674494640623225
570 */
571 static VALUE
572 random_seed(void)
573 {
574 unsigned int buf[DEFAULT_SEED_CNT];
575 fill_random_seed(buf);
576 return make_seed_value(buf);
577 }
578
579 /*
580 * call-seq: prng.seed -> integer
581 *
582 * Returns the seed value used to initialize the generator. This may be used to
583 * initialize another generator with the same state at a later time, causing it
584 * to produce the same sequence of numbers.
585 *
586 * prng1 = Random.new(1234)
587 * prng1.seed #=> 1234
588 * prng1.rand(100) #=> 47
589 *
590 * prng2 = Random.new(prng1.seed)
591 * prng2.rand(100) #=> 47
592 */
593 static VALUE
594 random_get_seed(VALUE obj)
595 {
596 return get_rnd(obj)->seed;
597 }
598
599 /* :nodoc: */
600 static VALUE
601 random_copy(VALUE obj, VALUE orig)
602 {
603 rb_random_t *rnd1, *rnd2;
604 struct MT *mt;
605
606 if (!OBJ_INIT_COPY(obj, orig)) return obj;
607
608 rnd1 = get_rnd(obj);
609 rnd2 = get_rnd(orig);
610 mt = &rnd1->mt;
611
612 *rnd1 = *rnd2;
613 mt->next = mt->state + numberof(mt->state) - mt->left + 1;
614 return obj;
615 }
616
617 static VALUE
618 mt_state(const struct MT *mt)
619 {
620 VALUE bigo = rb_big_new(sizeof(mt->state) / sizeof(BDIGIT), 1);
621 BDIGIT *d = RBIGNUM_DIGITS(bigo);
622 int i;
623
624 for (i = 0; i < numberof(mt->state); ++i) {
625 unsigned int x = mt->state[i];
626 #if SIZEOF_BDIGITS < SIZEOF_INT32
627 int j;
628 for (j = 0; j < SIZEOF_INT32 / SIZEOF_BDIGITS; ++j) {
629 *d++ = BIGLO(x);
630 x = BIGDN(x);
631 }
632 #else
633 *d++ = (BDIGIT)x;
634 #endif
635 }
636 return rb_big_norm(bigo);
637 }
638
639 /* :nodoc: */
640 static VALUE
641 random_state(VALUE obj)
642 {
643 rb_random_t *rnd = get_rnd(obj);
644 return mt_state(&rnd->mt);
645 }
646
647 /* :nodoc: */
648 static VALUE
649 random_s_state(VALUE klass)
650 {
651 return mt_state(&default_rand.mt);
652 }
653
654 /* :nodoc: */
655 static VALUE
656 random_left(VALUE obj)
657 {
658 rb_random_t *rnd = get_rnd(obj);
659 return INT2FIX(rnd->mt.left);
660 }
661
662 /* :nodoc: */
663 static VALUE
664 random_s_left(VALUE klass)
665 {
666 return INT2FIX(default_rand.mt.left);
667 }
668
669 /* :nodoc: */
670 static VALUE
671 random_dump(VALUE obj)
672 {
673 rb_random_t *rnd = get_rnd(obj);
674 VALUE dump = rb_ary_new2(3);
675
676 rb_ary_push(dump, mt_state(&rnd->mt));
677 rb_ary_push(dump, INT2FIX(rnd->mt.left));
678 rb_ary_push(dump, rnd->seed);
679
680 return dump;
681 }
682
683 /* :nodoc: */
684 static VALUE
685 random_load(VALUE obj, VALUE dump)
686 {
687 rb_random_t *rnd = get_rnd(obj);
688 struct MT *mt = &rnd->mt;
689 VALUE state, left = INT2FIX(1), seed = INT2FIX(0);
690 VALUE *ary;
691 unsigned long x;
692
693 rb_check_copyable(obj, dump);
694 Check_Type(dump, T_ARRAY);
695 ary = RARRAY_PTR(dump);
696 switch (RARRAY_LEN(dump)) {
697 case 3:
698 seed = ary[2];
699 case 2:
700 left = ary[1];
701 case 1:
702 state = ary[0];
703 break;
704 default:
705 rb_raise(rb_eArgError, "wrong dump data");
706 }
707 memset(mt->state, 0, sizeof(mt->state));
708 if (FIXNUM_P(state)) {
709 x = FIX2ULONG(state);
710 mt->state[0] = (unsigned int)x;
711 #if SIZEOF_LONG / SIZEOF_INT >= 2
712 mt->state[1] = (unsigned int)(x >> BITSPERDIG);
713 #endif
714 #if SIZEOF_LONG / SIZEOF_INT >= 3
715 mt->state[2] = (unsigned int)(x >> 2 * BITSPERDIG);
716 #endif
717 #if SIZEOF_LONG / SIZEOF_INT >= 4
718 mt->state[3] = (unsigned int)(x >> 3 * BITSPERDIG);
719 #endif
720 }
721 else {
722 BDIGIT *d;
723 long len;
724 Check_Type(state, T_BIGNUM);
725 len = RBIGNUM_LEN(state);
726 if (len > roomof(sizeof(mt->state), SIZEOF_BDIGITS)) {
727 len = roomof(sizeof(mt->state), SIZEOF_BDIGITS);
728 }
729 #if SIZEOF_BDIGITS < SIZEOF_INT
730 else if (len % DIGSPERINT) {
731 d = RBIGNUM_DIGITS(state) + len;
732 # if DIGSPERINT == 2
733 --len;
734 x = *--d;
735 # else
736 x = 0;
737 do {
738 x = (x << BITSPERDIG) | *--d;
739 } while (--len % DIGSPERINT);
740 # endif
741 mt->state[len / DIGSPERINT] = (unsigned int)x;
742 }
743 #endif
744 if (len > 0) {
745 d = BDIGITS(state) + len;
746 do {
747 --len;
748 x = *--d;
749 # if DIGSPERINT == 2
750 --len;
751 x = (x << BITSPERDIG) | *--d;
752 # elif SIZEOF_BDIGITS < SIZEOF_INT
753 do {
754 x = (x << BITSPERDIG) | *--d;
755 } while (--len % DIGSPERINT);
756 # endif
757 mt->state[len / DIGSPERINT] = (unsigned int)x;
758 } while (len > 0);
759 }
760 }
761 x = NUM2ULONG(left);
762 if (x > numberof(mt->state)) {
763 rb_raise(rb_eArgError, "wrong value");
764 }
765 mt->left = (unsigned int)x;
766 mt->next = mt->state + numberof(mt->state) - x + 1;
767 rnd->seed = rb_to_int(seed);
768
769 return obj;
770 }
771
772 /*
773 * call-seq:
774 * srand(number = Random.new_seed) -> old_seed
775 *
776 * Seeds the system pseudo-random number generator, Random::DEFAULT, with
777 * +number+. The previous seed value is returned.
778 *
779 * If +number+ is omitted, seeds the generator using a source of entropy
780 * provided by the operating system, if available (/dev/urandom on Unix systems
781 * or the RSA cryptographic provider on Windows), which is then combined with
782 * the time, the process id, and a sequence number.
783 *
784 * srand may be used to ensure repeatable sequences of pseudo-random numbers
785 * between different runs of the program. By setting the seed to a known value,
786 * programs can be made deterministic during testing.
787 *
788 * srand 1234 # => 268519324636777531569100071560086917274
789 * [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
790 * [ rand(10), rand(1000) ] # => [4, 664]
791 * srand 1234 # => 1234
792 * [ rand, rand ] # => [0.1915194503788923, 0.6221087710398319]
793 */
794
795 static VALUE
796 rb_f_srand(int argc, VALUE *argv, VALUE obj)
797 {
798 VALUE seed, old;
799 rb_random_t *r = &default_rand;
800
801 rb_secure(4);
802 if (argc == 0) {
803 seed = random_seed();
804 }
805 else {
806 rb_scan_args(argc, argv, "01", &seed);
807 }
808 old = r->seed;
809 r->seed = rand_init(&r->mt, seed);
810
811 return old;
812 }
813
814 static unsigned long
815 make_mask(unsigned long x)
816 {
817 x = x | x >> 1;
818 x = x | x >> 2;
819 x = x | x >> 4;
820 x = x | x >> 8;
821 x = x | x >> 16;
822 #if 4 < SIZEOF_LONG
823 x = x | x >> 32;
824 #endif
825 return x;
826 }
827
828 static unsigned long
829 limited_rand(struct MT *mt, unsigned long limit)
830 {
831 /* mt must be initialized */
832 int i;
833 unsigned long val, mask;
834
835 if (!limit) return 0;
836 mask = make_mask(limit);
837 retry:
838 val = 0;
839 for (i = SIZEOF_LONG/SIZEOF_INT32-1; 0 <= i; i--) {
840 if ((mask >> (i * 32)) & 0xffffffff) {
841 val |= (unsigned long)genrand_int32(mt) << (i * 32);
842 val &= mask;
843 if (limit < val)
844 goto retry;
845 }
846 }
847 return val;
848 }
849
850 static VALUE
851 limited_big_rand(struct MT *mt, struct RBignum *limit)
852 {
853 /* mt must be initialized */
854 unsigned long mask, lim, rnd;
855 struct RBignum *val;
856 long i, len;
857 int boundary;
858
859 len = (RBIGNUM_LEN(limit) * SIZEOF_BDIGITS + 3) / 4;
860 val = (struct RBignum *)rb_big_clone((VALUE)limit);
861 RBIGNUM_SET_SIGN(val, 1);
862 #if SIZEOF_BDIGITS == 2
863 # define BIG_GET32(big,i) \
864 (RBIGNUM_DIGITS(big)[(i)*2] | \
865 ((i)*2+1 < RBIGNUM_LEN(big) ? \
866 (RBIGNUM_DIGITS(big)[(i)*2+1] << 16) : \
867 0))
868 # define BIG_SET32(big,i,d) \
869 ((RBIGNUM_DIGITS(big)[(i)*2] = (d) & 0xffff), \
870 ((i)*2+1 < RBIGNUM_LEN(big) ? \
871 (RBIGNUM_DIGITS(big)[(i)*2+1] = (d) >> 16) : \
872 0))
873 #else
874 /* SIZEOF_BDIGITS == 4 */
875 # define BIG_GET32(big,i) (RBIGNUM_DIGITS(big)[(i)])
876 # define BIG_SET32(big,i,d) (RBIGNUM_DIGITS(big)[(i)] = (d))
877 #endif
878 retry:
879 mask = 0;
880 boundary = 1;
881 for (i = len-1; 0 <= i; i--) {
882 lim = BIG_GET32(limit, i);
883 mask = mask ? 0xffffffff : make_mask(lim);
884 if (mask) {
885 rnd = genrand_int32(mt) & mask;
886 if (boundary) {
887 if (lim < rnd)
888 goto retry;
889 if (rnd < lim)
890 boundary = 0;
891 }
892 }
893 else {
894 rnd = 0;
895 }
896 BIG_SET32(val, i, (BDIGIT)rnd);
897 }
898 return rb_big_norm((VALUE)val);
899 }
900
901 /*
902 * Returns random unsigned long value in [0, +limit+].
903 *
904 * Note that +limit+ is included, and the range of the argument and the
905 * return value depends on environments.
906 */
907 unsigned long
908 rb_genrand_ulong_limited(unsigned long limit)
909 {
910 return limited_rand(default_mt(), limit);
911 }
912
913 unsigned int
914 rb_random_int32(VALUE obj)
915 {
916 rb_random_t *rnd = try_get_rnd(obj);
917 if (!rnd) {
918 #if SIZEOF_LONG * CHAR_BIT > 32
919 VALUE lim = ULONG2NUM(0x100000000UL);
920 #elif defined HAVE_LONG_LONG
921 VALUE lim = ULL2NUM((LONG_LONG)0xffffffff+1);
922 #else
923 VALUE lim = rb_big_plus(ULONG2NUM(0xffffffff), INT2FIX(1));
924 #endif
925 return (unsigned int)NUM2ULONG(rb_funcall2(obj, id_rand, 1, &lim));
926 }
927 return genrand_int32(&rnd->mt);
928 }
929
930 double
931 rb_random_real(VALUE obj)
932 {
933 rb_random_t *rnd = try_get_rnd(obj);
934 if (!rnd) {
935 VALUE v = rb_funcall2(obj, id_rand, 0, 0);
936 double d = NUM2DBL(v);
937 if (d < 0.0) {
938 rb_raise(rb_eRangeError, "random number too small %g", d);
939 }
940 else if (d >= 1.0) {
941 rb_raise(rb_eRangeError, "random number too big %g", d);
942 }
943 return d;
944 }
945 return genrand_real(&rnd->mt);
946 }
947
948 static inline VALUE
949 ulong_to_num_plus_1(unsigned long n)
950 {
951 #if HAVE_LONG_LONG
952 return ULL2NUM((LONG_LONG)n+1);
953 #else
954 if (n >= ULONG_MAX) {
955 return rb_big_plus(ULONG2NUM(n), INT2FIX(1));
956 }
957 return ULONG2NUM(n+1);
958 #endif
959 }
960
961 unsigned long
962 rb_random_ulong_limited(VALUE obj, unsigned long limit)
963 {
964 rb_random_t *rnd = try_get_rnd(obj);
965 if (!rnd) {
966 extern int rb_num_negative_p(VALUE);
967 VALUE lim = ulong_to_num_plus_1(limit);
968 VALUE v = rb_to_int(rb_funcall2(obj, id_rand, 1, &lim));
969 unsigned long r = NUM2ULONG(v);
970 if (rb_num_negative_p(v)) {
971 rb_raise(rb_eRangeError, "random number too small %ld", r);
972 }
973 if (r > limit) {
974 rb_raise(rb_eRangeError, "random number too big %ld", r);
975 }
976 return r;
977 }
978 return limited_rand(&rnd->mt, limit);
979 }
980
981 /*
982 * call-seq: prng.bytes(size) -> a_string
983 *
984 * Returns a random binary string containing +size+ bytes.
985 *
986 * random_string = Random.new.bytes(10) # => "\xD7:R\xAB?\x83\xCE\xFAkO"
987 * random_string.size # => 10
988 */
989 static VALUE
990 random_bytes(VALUE obj, VALUE len)
991 {
992 return rb_random_bytes(obj, NUM2LONG(rb_to_int(len)));
993 }
994
995 VALUE
996 rb_random_bytes(VALUE obj, long n)
997 {
998 rb_random_t *rnd = try_get_rnd(obj);
999 VALUE bytes;
1000 char *ptr;
1001 unsigned int r, i;
1002
1003 if (!rnd) {
1004 VALUE len = LONG2NUM(n);
1005 return rb_funcall2(obj, id_bytes, 1, &len);
1006 }
1007 bytes = rb_str_new(0, n);
1008 ptr = RSTRING_PTR(bytes);
1009 for (; n >= SIZEOF_INT32; n -= SIZEOF_INT32) {
1010 r = genrand_int32(&rnd->mt);
1011 i = SIZEOF_INT32;
1012 do {
1013 *ptr++ = (char)r;
1014 r >>= CHAR_BIT;
1015 } while (--i);
1016 }
1017 if (n > 0) {
1018 r = genrand_int32(&rnd->mt);
1019 do {
1020 *ptr++ = (char)r;
1021 r >>= CHAR_BIT;
1022 } while (--n);
1023 }
1024 return bytes;
1025 }
1026
1027 static VALUE
1028 range_values(VALUE vmax, VALUE *begp, VALUE *endp, int *exclp)
1029 {
1030 VALUE end, r;
1031
1032 if (!rb_range_values(vmax, begp, &end, exclp)) return Qfalse;
1033 if (endp) *endp = end;
1034 if (!rb_respond_to(end, id_minus)) return Qfalse;
1035 r = rb_funcall2(end, id_minus, 1, begp);
1036 if (NIL_P(r)) return Qfalse;
1037 return r;
1038 }
1039
1040 static VALUE
1041 rand_int(struct MT *mt, VALUE vmax, int restrictive)
1042 {
1043 /* mt must be initialized */
1044 long max;
1045 unsigned long r;
1046
1047 if (FIXNUM_P(vmax)) {
1048 max = FIX2LONG(vmax);
1049 if (!max) return Qnil;
1050 if (max < 0) {
1051 if (restrictive) return Qnil;
1052 max = -max;
1053 }
1054 r = limited_rand(mt, (unsigned long)max - 1);
1055 return ULONG2NUM(r);
1056 }
1057 else {
1058 VALUE ret;
1059 if (rb_bigzero_p(vmax)) return Qnil;
1060 if (!RBIGNUM_SIGN(vmax)) {
1061 if (restrictive) return Qnil;
1062 vmax = rb_big_clone(vmax);
1063 RBIGNUM_SET_SIGN(vmax, 1);
1064 }
1065 vmax = rb_big_minus(vmax, INT2FIX(1));
1066 if (FIXNUM_P(vmax)) {
1067 max = FIX2LONG(vmax);
1068 if (max == -1) return Qnil;
1069 r = limited_rand(mt, max);
1070 return LONG2NUM(r);
1071 }
1072 ret = limited_big_rand(mt, RBIGNUM(vmax));
1073 RB_GC_GUARD(vmax);
1074 return ret;
1075 }
1076 }
1077
1078 static inline double
1079 float_value(VALUE v)
1080 {
1081 double x = RFLOAT_VALUE(v);
1082 if (isinf(x) || isnan(x)) {
1083 VALUE error = INT2FIX(EDOM);
1084 rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
1085 }
1086 return x;
1087 }
1088
1089 static inline VALUE
1090 rand_range(struct MT* mt, VALUE range)
1091 {
1092 VALUE beg = Qundef, end = Qundef, vmax, v;
1093 int excl = 0;
1094
1095 if ((v = vmax = range_values(range, &beg, &end, &excl)) == Qfalse)
1096 return Qfalse;
1097 if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
1098 long max;
1099 vmax = v;
1100 v = Qnil;
1101 if (FIXNUM_P(vmax)) {
1102 fixnum:
1103 if ((max = FIX2LONG(vmax) - excl) >= 0) {
1104 unsigned long r = limited_rand(mt, (unsigned long)max);
1105 v = ULONG2NUM(r);
1106 }
1107 }
1108 else if (BUILTIN_TYPE(vmax) == T_BIGNUM && RBIGNUM_SIGN(vmax) && !rb_bigzero_p(vmax)) {
1109 vmax = excl ? rb_big_minus(vmax, INT2FIX(1)) : rb_big_norm(vmax);
1110 if (FIXNUM_P(vmax)) {
1111 excl = 0;
1112 goto fixnum;
1113 }
1114 v = limited_big_rand(mt, RBIGNUM(vmax));
1115 }
1116 }
1117 else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
1118 int scale = 1;
1119 double max = RFLOAT_VALUE(v), mid = 0.5, r;
1120 if (isinf(max)) {
1121 double min = float_value(rb_to_float(beg)) / 2.0;
1122 max = float_value(rb_to_float(end)) / 2.0;
1123 scale = 2;
1124 mid = max + min;
1125 max -= min;
1126 }
1127 else {
1128 float_value(v);
1129 }
1130 v = Qnil;
1131 if (max > 0.0) {
1132 if (excl) {
1133 r = genrand_real(mt);
1134 }
1135 else {
1136 r = genrand_real2(mt);
1137 }
1138 if (scale > 1) {
1139 return rb_float_new(+(+(+(r - 0.5) * max) * scale) + mid);
1140 }
1141 v = rb_float_new(r * max);
1142 }
1143 else if (max == 0.0 && !excl) {
1144 v = rb_float_new(0.0);
1145 }
1146 }
1147
1148 if (FIXNUM_P(beg) && FIXNUM_P(v)) {
1149 long x = FIX2LONG(beg) + FIX2LONG(v);
1150 return LONG2NUM(x);
1151 }
1152 switch (TYPE(v)) {
1153 case T_NIL:
1154 break;
1155 case T_BIGNUM:
1156 return rb_big_plus(v, beg);
1157 case T_FLOAT: {
1158 VALUE f = rb_check_to_float(beg);
1159 if (!NIL_P(f)) {
1160 return DBL2NUM(RFLOAT_VALUE(v) + RFLOAT_VALUE(f));
1161 }
1162 }
1163 default:
1164 return rb_funcall2(beg, id_plus, 1, &v);
1165 }
1166
1167 return v;
1168 }
1169
1170 static VALUE rand_random(int argc, VALUE *argv, rb_random_t *rnd);
1171
1172 /*
1173 * call-seq:
1174 * prng.rand -> float
1175 * prng.rand(max) -> number
1176 *
1177 * When +max+ is an Integer, +rand+ returns a random integer greater than
1178 * or equal to zero and less than +max+. Unlike Kernel.rand, when +max+
1179 * is a negative integer or zero, +rand+ raises an ArgumentError.
1180 *
1181 * prng = Random.new
1182 * prng.rand(100) # => 42
1183 *
1184 * When +max+ is a Float, +rand+ returns a random floating point number
1185 * between 0.0 and +max+, including 0.0 and excluding +max+.
1186 *
1187 * prng.rand(1.5) # => 1.4600282860034115
1188 *
1189 * When +max+ is a Range, +rand+ returns a random number where
1190 * range.member?(number) == true.
1191 *
1192 * prng.rand(5..9) # => one of [5, 6, 7, 8, 9]
1193 * prng.rand(5...9) # => one of [5, 6, 7, 8]
1194 * prng.rand(5.0..9.0) # => between 5.0 and 9.0, including 9.0
1195 * prng.rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
1196 *
1197 * Both the beginning and ending values of the range must respond to subtract
1198 * (<tt>-</tt>) and add (<tt>+</tt>)methods, or rand will raise an
1199 * ArgumentError.
1200 */
1201 static VALUE
1202 random_rand(int argc, VALUE *argv, VALUE obj)
1203 {
1204 return rand_random(argc, argv, get_rnd(obj));
1205 }
1206
1207 static VALUE
1208 rand_random(int argc, VALUE *argv, rb_random_t *rnd)
1209 {
1210 VALUE vmax, v;
1211
1212 if (argc == 0) {
1213 return rb_float_new(genrand_real(&rnd->mt));
1214 }
1215 else {
1216 rb_check_arity(argc, 0, 1);
1217 }
1218 vmax = argv[0];
1219 if (NIL_P(vmax)) {
1220 v = Qnil;
1221 }
1222 else if (!RB_TYPE_P(vmax, T_FLOAT) && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
1223 v = rand_int(&rnd->mt, v, 1);
1224 }
1225 else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
1226 double max = float_value(v);
1227 if (max > 0.0)
1228 v = rb_float_new(max * genrand_real(&rnd->mt));
1229 else
1230 v = Qnil;
1231 }
1232 else if ((v = rand_range(&rnd->mt, vmax)) != Qfalse) {
1233 /* nothing to do */
1234 }
1235 else {
1236 v = Qnil;
1237 (void)NUM2LONG(vmax);
1238 }
1239 if (NIL_P(v)) {
1240 VALUE mesg = rb_str_new_cstr("invalid argument - ");
1241 rb_str_append(mesg, rb_obj_as_string(argv[0]));
1242 rb_exc_raise(rb_exc_new3(rb_eArgError, mesg));
1243 }
1244
1245 return v;
1246 }
1247
1248 /*
1249 * call-seq:
1250 * prng1 == prng2 -> true or false
1251 *
1252 * Returns true if the two generators have the same internal state, otherwise
1253 * false. Equivalent generators will return the same sequence of
1254 * pseudo-random numbers. Two generators will generally have the same state
1255 * only if they were initialized with the same seed
1256 *
1257 * Random.new == Random.new # => false
1258 * Random.new(1234) == Random.new(1234) # => true
1259 *
1260 * and have the same invocation history.
1261 *
1262 * prng1 = Random.new(1234)
1263 * prng2 = Random.new(1234)
1264 * prng1 == prng2 # => true
1265 *
1266 * prng1.rand # => 0.1915194503788923
1267 * prng1 == prng2 # => false
1268 *
1269 * prng2.rand # => 0.1915194503788923
1270 * prng1 == prng2 # => true
1271 */
1272 static VALUE
1273 random_equal(VALUE self, VALUE other)
1274 {
1275 rb_random_t *r1, *r2;
1276 if (rb_obj_class(self) != rb_obj_class(other)) return Qfalse;
1277 r1 = get_rnd(self);
1278 r2 = get_rnd(other);
1279 if (!RTEST(rb_funcall2(r1->seed, rb_intern("=="), 1, &r2->seed))) return Qfalse;
1280 if (memcmp(r1->mt.state, r2->mt.state, sizeof(r1->mt.state))) return Qfalse;
1281 if ((r1->mt.next - r1->mt.state) != (r2->mt.next - r2->mt.state)) return Qfalse;
1282 if (r1->mt.left != r2->mt.left) return Qfalse;
1283 return Qtrue;
1284 }
1285
1286 /*
1287 * call-seq:
1288 * rand(max=0) -> number
1289 *
1290 * If called without an argument, or if <tt>max.to_i.abs == 0</tt>, rand
1291 * returns a pseudo-random floating point number between 0.0 and 1.0,
1292 * including 0.0 and excluding 1.0.
1293 *
1294 * rand #=> 0.2725926052826416
1295 *
1296 * When +max.abs+ is greater than or equal to 1, +rand+ returns a pseudo-random
1297 * integer greater than or equal to 0 and less than +max.to_i.abs+.
1298 *
1299 * rand(100) #=> 12
1300 *
1301 * When +max+ is a Range, +rand+ returns a random number where
1302 * range.member?(number) == true.
1303 *
1304 * Negative or floating point values for +max+ are allowed, but may give
1305 * surprising results.
1306 *
1307 * rand(-100) # => 87
1308 * rand(-0.5) # => 0.8130921818028143
1309 * rand(1.9) # equivalent to rand(1), which is always 0
1310 *
1311 * Kernel.srand may be used to ensure that sequences of random numbers are
1312 * reproducible between different runs of a program.
1313 *
1314 * See also Random.rand.
1315 */
1316
1317 static VALUE
1318 rb_f_rand(int argc, VALUE *argv, VALUE obj)
1319 {
1320 VALUE v, vmax, r;
1321 struct MT *mt = default_mt();
1322
1323 if (argc == 0) goto zero_arg;
1324 rb_scan_args(argc, argv, "01", &vmax);
1325 if (NIL_P(vmax)) goto zero_arg;
1326 if ((v = rand_range(mt, vmax)) != Qfalse) {
1327 return v;
1328 }
1329 vmax = rb_to_int(vmax);
1330 if (vmax == INT2FIX(0) || NIL_P(r = rand_int(mt, vmax, 0))) {
1331 zero_arg:
1332 return DBL2NUM(genrand_real(mt));
1333 }
1334 return r;
1335 }
1336
1337 /*
1338 * call-seq:
1339 * Random.rand -> float
1340 * Random.rand(max) -> number
1341 *
1342 * Alias of Random::DEFAULT.rand.
1343 */
1344
1345 static VALUE
1346 random_s_rand(int argc, VALUE *argv, VALUE obj)
1347 {
1348 return rand_random(argc, argv, rand_start(&default_rand));
1349 }
1350
1351 #define SIP_HASH_STREAMING 0
1352 #define sip_hash24 ruby_sip_hash24
1353 #if !defined _WIN32 && !defined BYTE_ORDER
1354 # ifdef WORDS_BIGENDIAN
1355 # define BYTE_ORDER BIG_ENDIAN
1356 # else
1357 # define BYTE_ORDER LITTLE_ENDIAN
1358 # endif
1359 # ifndef LITTLE_ENDIAN
1360 # define LITTLE_ENDIAN 1234
1361 # endif
1362 # ifndef BIG_ENDIAN
1363 # define BIG_ENDIAN 4321
1364 # endif
1365 #endif
1366 #include "siphash.c"
1367
1368 static st_index_t hashseed;
1369 static union {
1370 uint8_t key[16];
1371 uint32_t u32[(16 * sizeof(uint8_t) - 1) / sizeof(uint32_t)];
1372 } sipseed;
1373
1374 static VALUE
1375 init_randomseed(struct MT *mt, unsigned int initial[DEFAULT_SEED_CNT])
1376 {
1377 VALUE seed;
1378 fill_random_seed(initial);
1379 init_by_array(mt, initial, DEFAULT_SEED_CNT);
1380 seed = make_seed_value(initial);
1381 memset(initial, 0, DEFAULT_SEED_LEN);
1382 return seed;
1383 }
1384
1385 void
1386 Init_RandomSeed(void)
1387 {
1388 rb_random_t *r = &default_rand;
1389 unsigned int initial[DEFAULT_SEED_CNT];
1390 struct MT *mt = &r->mt;
1391 VALUE seed = init_randomseed(mt, initial);
1392 int i;
1393
1394 hashseed = genrand_int32(mt);
1395 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8
1396 hashseed <<= 32;
1397 hashseed |= genrand_int32(mt);
1398 #endif
1399 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
1400 hashseed <<= 32;
1401 hashseed |= genrand_int32(mt);
1402 #endif
1403 #if SIZEOF_ST_INDEX_T*CHAR_BIT > 12*8
1404 hashseed <<= 32;
1405 hashseed |= genrand_int32(mt);
1406 #endif
1407
1408 for (i = 0; i < numberof(sipseed.u32); ++i)
1409 sipseed.u32[i] = genrand_int32(mt);
1410
1411 rb_global_variable(&r->seed);
1412 r->seed = seed;
1413 }
1414
1415 st_index_t
1416 rb_hash_start(st_index_t h)
1417 {
1418 return st_hash_start(hashseed + h);
1419 }
1420
1421 st_index_t
1422 rb_memhash(const void *ptr, long len)
1423 {
1424 sip_uint64_t h = sip_hash24(sipseed.key, ptr, len);
1425 #ifdef HAVE_UINT64_T
1426 return (st_index_t)h;
1427 #else
1428 return (st_index_t)(h.u32[0] ^ h.u32[1]);
1429 #endif
1430 }
1431
1432 static void
1433 Init_RandomSeed2(void)
1434 {
1435 VALUE seed = default_rand.seed;
1436
1437 if (RB_TYPE_P(seed, T_BIGNUM)) {
1438 RBASIC(seed)->klass = rb_cBignum;
1439 }
1440 }
1441
1442 void
1443 rb_reset_random_seed(void)
1444 {
1445 rb_random_t *r = &default_rand;
1446 uninit_genrand(&r->mt);
1447 r->seed = INT2FIX(0);
1448 }
1449
1450 /*
1451 * Document-class: Random
1452 *
1453 * Random provides an interface to Ruby's pseudo-random number generator, or
1454 * PRNG. The PRNG produces a deterministic sequence of bits which approximate
1455 * true randomness. The sequence may be represented by integers, floats, or
1456 * binary strings.
1457 *
1458 * The generator may be initialized with either a system-generated or
1459 * user-supplied seed value by using Random.srand.
1460 *
1461 * The class method Random.rand provides the base functionality of Kernel.rand
1462 * along with better handling of floating point values. These are both
1463 * interfaces to Random::DEFAULT, the Ruby system PRNG.
1464 *
1465 * Random.new will create a new PRNG with a state independent of
1466 * Random::DEFAULT, allowing multiple generators with different seed values or
1467 * sequence positions to exist simultaneously. Random objects can be
1468 * marshaled, allowing sequences to be saved and resumed.
1469 *
1470 * PRNGs are currently implemented as a modified Mersenne Twister with a period
1471 * of 2**19937-1.
1472 */
1473
1474 void
1475 Init_Random(void)
1476 {
1477 Init_RandomSeed2();
1478 rb_define_global_function("srand", rb_f_srand, -1);
1479 rb_define_global_function("rand", rb_f_rand, -1);
1480
1481 rb_cRandom = rb_define_class("Random", rb_cObject);
1482 rb_define_alloc_func(rb_cRandom, random_alloc);
1483 rb_define_method(rb_cRandom, "initialize", random_init, -1);
1484 rb_define_method(rb_cRandom, "rand", random_rand, -1);
1485 rb_define_method(rb_cRandom, "bytes", random_bytes, 1);
1486 rb_define_method(rb_cRandom, "seed", random_get_seed, 0);
1487 rb_define_method(rb_cRandom, "initialize_copy", random_copy, 1);
1488 rb_define_private_method(rb_cRandom, "marshal_dump", random_dump, 0);
1489 rb_define_private_method(rb_cRandom, "marshal_load", random_load, 1);
1490 rb_define_private_method(rb_cRandom, "state", random_state, 0);
1491 rb_define_private_method(rb_cRandom, "left", random_left, 0);
1492 rb_define_method(rb_cRandom, "==", random_equal, 1);
1493
1494 {
1495 VALUE rand_default = TypedData_Wrap_Struct(rb_cRandom, &random_data_type, &default_rand);
1496 rb_gc_register_mark_object(rand_default);
1497 rb_define_const(rb_cRandom, "DEFAULT", rand_default);
1498 }
1499
1500 rb_define_singleton_method(rb_cRandom, "srand", rb_f_srand, -1);
1501 rb_define_singleton_method(rb_cRandom, "rand", random_s_rand, -1);
1502 rb_define_singleton_method(rb_cRandom, "new_seed", random_seed, 0);
1503 rb_define_private_method(CLASS_OF(rb_cRandom), "state", random_s_state, 0);
1504 rb_define_private_method(CLASS_OF(rb_cRandom), "left", random_s_left, 0);
1505
1506 id_rand = rb_intern("rand");
1507 id_bytes = rb_intern("bytes");
1508 }
Init_Random
void Init_Random(void)
Definition: random.c:1475
RB_TYPE_P
#define RB_TYPE_P(obj, type)
RARRAY_PTR
RARRAY_PTR(q->result)[0]
rb_bigzero_p
int rb_bigzero_p(VALUE x)
Definition: bignum.c:91
random_bytes
static VALUE random_bytes(VALUE obj, VALUE len)
Definition: random.c:990
rb_to_int
VALUE rb_to_int(VALUE)
Definition: object.c:2431
rb_big_clone
VALUE rb_big_clone(VALUE x)
Definition: bignum.c:192
n
ssize_t n
Definition: bigdecimal.c:5655
default_rand
static rb_random_t default_rand
Definition: random.c:228
ary
volatile VALUE ary
Definition: tcltklib.c:9713
int
VP_EXPORT int
Definition: bigdecimal.c:5050
MT::state
unsigned int state[N]
Definition: random.c:104
gettimeofday
int gettimeofday(struct timeval *, struct timezone *)
Definition: win32.c:4013
random_s_state
static VALUE random_s_state(VALUE klass)
Definition: random.c:649
rb_class_new_instance
VALUE rb_class_new_instance(int, VALUE *, VALUE)
Definition: object.c:1775
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
st_hash_start
#define st_hash_start(h)
p
Win32OLEIDispatch * p
Definition: win32ole.c:786
u32
uint32_t u32[(16 *sizeof(uint8_t)-1)/sizeof(uint32_t)]
Definition: random.c:1371
make_mask
static unsigned long make_mask(unsigned long x)
Definition: random.c:815
max
static int max(int a, int b)
Definition: strftime.c:141
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1497
SIZEOF_BDIGITS
#define SIZEOF_BDIGITS
Definition: ripper.y:185
ruby.h
BIG_SET32
#define BIG_SET32(big, i, d)
rb_secure
void rb_secure(int)
Definition: safe.c:79
random_copy
static VALUE random_copy(VALUE obj, VALUE orig)
Definition: random.c:601
i
ssize_t i
Definition: bigdecimal.c:5655
rb_genrand_real
double rb_genrand_real(void)
Definition: random.c:257
rb_check_frozen
#define rb_check_frozen(obj)
sip_uint64_t
Definition: siphash.h:12
rb_big_plus
VALUE rb_big_plus(VALUE x, VALUE y)
Definition: bignum.c:2031
random_rand
static VALUE random_rand(int argc, VALUE *argv, VALUE obj)
Definition: random.c:1202
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
rb_str_new_cstr
VALUE rb_str_new_cstr(const char *)
Definition: string.c:447
random_left
static VALUE random_left(VALUE obj)
Definition: random.c:656
ret
int ret
Definition: tcltklib.c:280
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1356
rand_int
static VALUE rand_int(struct MT *mt, VALUE vmax, int restrictive)
Definition: random.c:1041
RBIGNUM_SIGN
#define RBIGNUM_SIGN(b)
a
Real * a
Definition: bigdecimal.c:1182
random_seed
static VALUE random_seed(void)
Definition: random.c:572
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:511
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_update_max_fd
void rb_update_max_fd(int fd)
Definition: io.c:164
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
TYPE
#define TYPE(x)
NUM2ULONG
#define NUM2ULONG(x)
rand_start
static rb_random_t * rand_start(rb_random_t *r)
Definition: random.c:234
random_mark
static void random_mark(void *ptr)
Definition: random.c:334
RSTRING_PTR
#define RSTRING_PTR(str)
CLASS_OF
#define CLASS_OF(v)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
DEFAULT_SEED_CNT
#define DEFAULT_SEED_CNT
Definition: random.c:226
T_ARRAY
#define T_ARRAY
random_equal
static VALUE random_equal(VALUE self, VALUE other)
Definition: random.c:1273
xfree
#define xfree
MEMMOVE
#define MEMMOVE(p1, p2, type, n)
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
genrand_int32
static unsigned int genrand_int32(struct MT *mt)
Definition: random.c:180
init_by_array
static void init_by_array(struct MT *mt, unsigned int init_key[], int key_length)
Definition: random.c:135
Qtrue
return Qtrue
Definition: tcltklib.c:9610
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:194
sip_uint64_t::u32
uint32_t u32[2]
Definition: siphash.h:13
MT::left
int left
Definition: random.c:106
rb_num_negative_p
int rb_num_negative_p(VALUE)
Definition: numeric.c:189
fill_random_seed
static void fill_random_seed(unsigned int seed[DEFAULT_SEED_CNT])
Definition: random.c:488
T_NIL
#define T_NIL
genrand_real2
static double genrand_real2(struct MT *mt)
Definition: random.c:209
r
r
Definition: bigdecimal.c:1196
rb_big2dbl
double rb_big2dbl(VALUE x)
Definition: bignum.c:1429
RBignum
Definition: ripper.y:1059
rb_define_global_function
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1526
timeval::tv_sec
long tv_sec
Definition: ossl_asn1.c:17
random_free
static void random_free(void *ptr)
Definition: random.c:340
state
int state
Definition: tcltklib.c:1462
rb_big_resize
void rb_big_resize(VALUE big, long len)
Definition: bignum.c:160
rb_random_t
Definition: random.c:221
random_s_left
static VALUE random_s_left(VALUE klass)
Definition: random.c:664
rb_random_bytes
VALUE rb_random_bytes(VALUE rnd, long n)
Definition: random.c:996
rb_big_new
VALUE rb_big_new(long len, int sign)
Definition: bignum.c:186
T_FLOAT
#define T_FLOAT
limited_big_rand
static VALUE limited_big_rand(struct MT *mt, struct RBignum *limit)
Definition: random.c:851
LONG2NUM
#define LONG2NUM(x)
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2121
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:515
d
d
Definition: strlcat.c:58
FIX2ULONG
#define FIX2ULONG(x)
uint8_t
unsigned char uint8_t
Definition: sha2.h:100
rb_hash_start
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1416
RBIGNUM_LEN
#define RBIGNUM_LEN(b)
MEMZERO
#define MEMZERO(p, type, n)
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Definition: eval.c:527
MT_MAX_STATE
Definition: random.c:100
random_memsize
static size_t random_memsize(const void *ptr)
Definition: random.c:347
rb_float_new
static VALUE rb_float_new(double d)
Definition: ripper.y:790
rb_genrand_ulong_limited
unsigned long rb_genrand_ulong_limited(unsigned long i)
Definition: random.c:908
next_state
static void next_state(struct MT *mt)
Definition: random.c:161
rb_check_to_float
VALUE rb_check_to_float(VALUE)
Definition: object.c:2706
id_minus
#define id_minus
Definition: random.c:328
id_plus
#define id_plus
Definition: random.c:329
init_randomseed
static VALUE init_randomseed(struct MT *mt, unsigned int initial[DEFAULT_SEED_CNT])
Definition: random.c:1375
memset
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
Init_RandomSeed2
static void Init_RandomSeed2(void)
Definition: random.c:1433
m
BDIGIT m
Definition: bigdecimal.c:5085
hashseed
static st_index_t hashseed
Definition: random.c:1368
Qfalse
return Qfalse
Definition: tcltklib.c:6779
FIXNUM_P
#define FIXNUM_P(f)
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
RARRAY_LEN
#define RARRAY_LEN(a)
NUM2DBL
#define NUM2DBL(x)
Qnil
#define Qnil
Definition: tcltklib.c:1896
val
#define val
Definition: tcltklib.c:1949
timeval::tv_usec
long tv_usec
Definition: ossl_asn1.c:18
rb_random_real
double rb_random_real(VALUE rnd)
Definition: random.c:931
mt_state
static VALUE mt_state(const struct MT *mt)
Definition: random.c:618
random_init
static VALUE random_init(int argc, VALUE *argv, VALUE obj)
Definition: random.c:462
rb_typeddata_is_kind_of
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:473
rb_f_srand
static VALUE rb_f_srand(int argc, VALUE *argv, VALUE obj)
Definition: random.c:796
Check_Type
#define Check_Type(v, t)
ID
unsigned long ID
Definition: ripper.y:105
rb_gc_mark
void rb_gc_mark(VALUE)
Definition: gc.c:2598
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2202
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
INT2FIX
#define INT2FIX(i)
rb_check_to_integer
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2417
unistd.h
FIX2LONG
#define FIX2LONG(x)
SIZEOF_INT32
#define SIZEOF_INT32
Definition: random.c:274
random_data_type
static const rb_data_type_t random_data_type
Definition: random.c:352
OBJ_INIT_COPY
#define OBJ_INIT_COPY(obj, orig)
M
#define M
Definition: random.c:93
S_ISCHR
#define S_ISCHR(m)
TypedData_Wrap_Struct
#define TypedData_Wrap_Struct(klass, data_type, sval)
range
#define range(low, item, hi)
Definition: date_strftime.c:21
genrand_initialized
#define genrand_initialized(mt)
Definition: random.c:109
siphash.c
int_pair_to_real_inclusive
static double int_pair_to_real_inclusive(unsigned int a, unsigned int b)
Definition: random.c:277
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
uninit_genrand
#define uninit_genrand(mt)
Definition: random.c:110
DBL2NUM
#define DBL2NUM(dbl)
key
static int VALUE key
Definition: tkutil.c:265
id_bytes
static ID id_bytes
Definition: random.c:330
U
Definition: util.c:789
rb_range_values
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Definition: range.c:963
RBIGNUM_DIGITS
#define RBIGNUM_DIGITS(b)
range_values
static VALUE range_values(VALUE vmax, VALUE *begp, VALUE *endp, int *exclp)
Definition: random.c:1028
rb_random_t::seed
VALUE seed
Definition: random.c:222
rb_obj_as_string
VALUE rb_obj_as_string(VALUE)
Definition: string.c:895
argv
VALUE * argv
Definition: tcltklib.c:1971
BIGLO
#define BIGLO(x)
Definition: random.c:269
rb_big_minus
VALUE rb_big_minus(VALUE x, VALUE y)
Definition: bignum.c:2068
RTEST
#define RTEST(v)
RBIGNUM_SET_SIGN
#define RBIGNUM_SET_SIGN(b, sign)
random_load
static VALUE random_load(VALUE obj, VALUE dump)
Definition: random.c:685
timeval
Definition: ossl_asn1.c:16
rb_eSystemCallError
VALUE rb_eSystemCallError
Definition: error.c:529
s
register char * s
Definition: os2.c:56
BIGDN
#define BIGDN(x)
Definition: random.c:268
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE)
Definition: gc.c:2980
make_seed_value
static VALUE make_seed_value(const void *ptr)
Definition: random.c:539
void
VP_EXPORT void
Definition: bigdecimal.c:5083
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
min
static int min(int a, int b)
Definition: strftime.c:131
rb_genrand_int32
unsigned int rb_genrand_int32(void)
Definition: random.c:250
RB_GC_GUARD
#define RB_GC_GUARD(v)
T_FIXNUM
#define T_FIXNUM
rb_big_mul
VALUE rb_big_mul(VALUE x, VALUE y)
Definition: bignum.c:2660
argc
int argc
Definition: tcltklib.c:1970
BDIGIT
#define BDIGIT
Definition: ripper.y:184
rb_check_copyable
void rb_check_copyable(VALUE obj, VALUE orig)
Definition: error.c:2001
memcmp
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
isinf
RUBY_EXTERN int isinf(double)
Definition: isinf.c:56
isnan
#define isnan(x)
Definition: win32.h:327
rb_random_int32
unsigned int rb_random_int32(VALUE rnd)
Definition: random.c:914
random_dump
static VALUE random_dump(VALUE obj)
Definition: random.c:671
b
Real * b
Definition: bigdecimal.c:1182
ptr
return ptr
Definition: tcltklib.c:784
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:208
T_BIGNUM
#define T_BIGNUM
uint32_t
unsigned int uint32_t
Definition: sha2.h:101
MEMCPY
#define MEMCPY(p1, p2, type, n)
MT
Definition: random.c:102
end
gz end
Definition: zlib.c:2272
genrand_real
static double genrand_real(struct MT *mt)
Definition: random.c:199
NEWOBJ_OF
#define NEWOBJ_OF(obj, type, klass, flags)
rb_random_ulong_limited
unsigned long rb_random_ulong_limited(VALUE rnd, unsigned long limit)
Definition: random.c:962
f
#define f
NUM2LONG
#define NUM2LONG(x)
numberof
#define numberof(array)
Definition: random.c:273
rb_cBignum
VALUE rb_cBignum
Definition: bignum.c:28
float_value
static double float_value(VALUE v)
Definition: random.c:1079
sipseed
static union @120 sipseed
Qundef
#define Qundef
rb_exc_new3
VALUE rb_exc_new3(VALUE etype, VALUE str)
Definition: error.c:548
BIG_GET32
#define BIG_GET32(big, i)
RBIGNUM
#define RBIGNUM(obj)
rb_memhash
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1422
random_alloc
static VALUE random_alloc(VALUE klass)
Definition: random.c:381
rb_data_type_struct
Definition: ripper.y:960
DATA_PTR
DATA_PTR(self)
roomof
#define roomof(n, m)
Definition: random.c:272
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
TWIST
#define TWIST(u, v)
Definition: random.c:98
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
st_index_t
st_data_t st_index_t
Definition: ripper.y:63
ALLOC_N
#define ALLOC_N(type, n)
rb_big_norm
VALUE rb_big_norm(VALUE x)
Definition: bignum.c:282
RBASIC
#define RBASIC(obj)
rb_f_rand
static VALUE rb_f_rand(int argc, VALUE *argv, VALUE obj)
Definition: random.c:1318
O_NONBLOCK
#define O_NONBLOCK
Definition: win32.h:591
id_rand
static ID id_rand
Definition: random.c:330
klass
klass
Definition: tcltklib.c:3504
rand_init
static VALUE rand_init(struct MT *mt, VALUE vseed)
Definition: random.c:390
get_rnd
static rb_random_t * get_rnd(VALUE obj)
Definition: random.c:362
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1564
limited_rand
static unsigned long limited_rand(struct MT *mt, unsigned long limit)
Definition: random.c:829
N
#define N
Definition: random.c:92
BITSPERDIG
#define BITSPERDIG
Definition: random.c:264
random_s_rand
static VALUE random_s_rand(int argc, VALUE *argv, VALUE obj)
Definition: random.c:1346
rb_ary_new2
VALUE rb_ary_new2(long capa)
Definition: array.c:417
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:425
BDIGITS
#define BDIGITS(x)
Definition: random.c:263
rb_cloexec_open
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
Definition: io.c:209
init_genrand
static void init_genrand(struct MT *mt, unsigned int s)
Definition: random.c:114
DIGSPERINT
#define DIGSPERINT
Definition: random.c:266
rb_check_arity
#define rb_check_arity(argc, min, max)
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
rb_global_variable
void rb_global_variable(VALUE *)
Definition: gc.c:426
rb_cRandom
RUBY_EXTERN VALUE rb_cRandom
Definition: ripper.y:1450
rb_funcall2
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:805
VALUE
unsigned long VALUE
Definition: ripper.y:104
default_mt
static struct MT * default_mt(void)
Definition: random.c:244
rb_to_float
VALUE rb_to_float(VALUE)
Definition: object.c:2692
rb_big_rshift
VALUE rb_big_rshift(VALUE x, VALUE y)
Definition: bignum.c:3608
ulong_to_num_plus_1
static VALUE ulong_to_num_plus_1(unsigned long n)
Definition: random.c:949
sip_hash24
#define sip_hash24
Definition: random.c:1352
random_get_seed
static VALUE random_get_seed(VALUE obj)
Definition: random.c:594
rb_intern
#define rb_intern(str)
v
BDIGIT v
Definition: bigdecimal.c:5656
fstat
#define fstat(fd, st)
Definition: win32.h:194
stat
#define stat(path, st)
Definition: win32.h:193
NULL
#define NULL
Definition: _sdbm.c:103
rand_random
static VALUE rand_random(int argc, VALUE *argv, rb_random_t *rnd)
Definition: random.c:1208
rb_random_t::mt
struct MT mt
Definition: random.c:223
Init_RandomSeed
void Init_RandomSeed(void)
Definition: random.c:1386
try_get_rnd
static rb_random_t * try_get_rnd(VALUE obj)
Definition: random.c:370
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
retry
int retry
Definition: tcltklib.c:10151
DEFAULT_SEED_LEN
#define DEFAULT_SEED_LEN
Definition: random.c:479
random_state
static VALUE random_state(VALUE obj)
Definition: random.c:641
ULONG2NUM
#define ULONG2NUM(x)
MT::next
unsigned int * next
Definition: random.c:105
rb_eArgError
VALUE rb_eArgError
Definition: error.c:512
int_must_be_32bit_at_least
int int_must_be_32bit_at_least[sizeof(int)*CHAR_BIT< 32?-1:1]
Definition: random.c:89
rb_reset_random_seed
void rb_reset_random_seed(void)
Definition: random.c:1443
rand_range
static VALUE rand_range(struct MT *mt, VALUE range)
Definition: random.c:1090
len
size_t len
Definition: tcltklib.c:3568