diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-08 06:46:45 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-08 06:46:45 +0000 |
commit | ccce83c454880c9a0414f8b750ca0808e1f40ccc (patch) | |
tree | 6ca01f5879cf578ad4c0ed7f79fb1f2a92b83031 /random.c | |
parent | 90b1a8f4310db9b46f76fa549f981b7deef93f47 (diff) | |
download | ruby-ccce83c454880c9a0414f8b750ca0808e1f40ccc.tar.gz |
* random.c (rand_init): Use rb_integer_pack.
(roomof): Removed.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41167 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'random.c')
-rw-r--r-- | random.c | 67 |
1 files changed, 21 insertions, 46 deletions
@@ -270,7 +270,6 @@ rb_genrand_real(void) #define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1))) #define BDIGMAX ((BDIGIT)-1) -#define roomof(n, m) (int)(((n)+(m)-1) / (m)) #define SIZEOF_INT32 (31/CHAR_BIT + 1) static double @@ -379,58 +378,34 @@ static VALUE rand_init(struct MT *mt, VALUE vseed) { volatile VALUE seed; - long blen = 0; - long fixnum_seed; - int i, j, len; - unsigned int buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0; + uint32_t buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0; + size_t len; + int sign; seed = rb_to_int(vseed); - switch (TYPE(seed)) { - case T_FIXNUM: - len = 1; - fixnum_seed = FIX2LONG(seed); - if (fixnum_seed < 0) - fixnum_seed = -fixnum_seed; - buf[0] = (unsigned int)(fixnum_seed & 0xffffffff); -#if SIZEOF_LONG > SIZEOF_INT32 - if ((long)(int32_t)fixnum_seed != fixnum_seed) { - if ((buf[1] = (unsigned int)(fixnum_seed >> 32)) != 0) ++len; - } -#endif - break; - case T_BIGNUM: - blen = RBIGNUM_LEN(seed); - if (blen == 0) { - len = 1; - } - else { - if (blen > MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS) - blen = MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS; - len = roomof((int)blen * SIZEOF_BDIGITS, SIZEOF_INT32); - } - /* allocate ints for init_by_array */ - if (len > numberof(buf0)) buf = ALLOC_N(unsigned int, len); - memset(buf, 0, len * sizeof(*buf)); - len = 0; - for (i = (int)(blen-1); 0 <= i; i--) { - j = i * SIZEOF_BDIGITS / SIZEOF_INT32; -#if SIZEOF_BDIGITS < SIZEOF_INT32 - buf[j] <<= BITSPERDIG; -#endif - buf[j] |= RBIGNUM_DIGITS(seed)[i]; - if (!len && buf[j]) len = j; - } - ++len; - break; - default: - rb_raise(rb_eTypeError, "failed to convert %s into Integer", - rb_obj_classname(vseed)); + + len = rb_absint_size_in_word(seed, 32, NULL); + if (MT_MAX_STATE < len) + len = MT_MAX_STATE; + if (len > numberof(buf0)) + buf = ALLOC_N(unsigned int, len); + rb_integer_pack(seed, &sign, NULL, buf, len, sizeof(uint32_t), 0, + INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER); + if (sign < 0) + sign = -sign; + if (sign != 2) { /* not overflow */ + while (0 < len && buf[len-1] == 0) + len--; + } + if (len == 0) { + buf[0] = 0; + len = 1; } if (len <= 1) { init_genrand(mt, buf[0]); } else { - if (buf[len-1] == 1) /* remove leading-zero-guard */ + if (sign != 2 && buf[len-1] == 1) /* remove leading-zero-guard */ len--; init_by_array(mt, buf, len); } |