Ruby 2.1.5p273(2014-11-13revision48405)

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