From ccce83c454880c9a0414f8b750ca0808e1f40ccc Mon Sep 17 00:00:00 2001 From: akr Date: Sat, 8 Jun 2013 06:46:45 +0000 Subject: * 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 --- ChangeLog | 5 +++++ random.c | 67 ++++++++++++++++++++------------------------------------------- 2 files changed, 26 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index a38295fbf2..6072b53c3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Jun 8 15:30:03 2013 Tanaka Akira + + * random.c (rand_init): Use rb_integer_pack. + (roomof): Removed. + Sat Jun 8 14:58:32 2013 Tanaka Akira * internal.h (INTEGER_PACK_FORCE_BIGNUM): New flag constant. diff --git a/random.c b/random.c index b9869f9b11..19b65a7083 100644 --- a/random.c +++ b/random.c @@ -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); } -- cgit v1.2.3