diff --git a/ChangeLog b/ChangeLog index a3a25a7a6f..c3cb8ac1f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Mon Dec 29 22:27:11 2008 Yukihiro Matsumoto + + * random.c (rb_f_rand): type check simplified. strings are no + longer allowed for argument. [ruby-dev:37655] + + * test/ruby/test_rand.rb (TestRand::o.to_int): need override + to_int. + Mon Dec 29 21:22:31 2008 Tadayoshi Funaba * numeric.c: Infinity.numerator returns self. [experimental] diff --git a/random.c b/random.c index a677c1b3f5..912039a31c 100644 --- a/random.c +++ b/random.c @@ -489,49 +489,31 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj) long val, max; struct MT *mt = &default_mt.mt; - rb_scan_args(argc, argv, "01", &vmax); if (!genrand_initialized(mt)) { rand_init(mt, random_seed()); } - switch (TYPE(vmax)) { - case T_FLOAT: - if (RFLOAT_VALUE(vmax) <= LONG_MAX && RFLOAT_VALUE(vmax) >= LONG_MIN) { - max = (long)RFLOAT_VALUE(vmax); - break; + if (argc == 0) goto zero_arg; + rb_scan_args(argc, argv, "01", &vmax); + if (NIL_P(vmax)) goto zero_arg; + vmax = rb_to_int(vmax); + if (TYPE(vmax) == T_BIGNUM) { + struct RBignum *limit = (struct RBignum *)vmax; + if (!RBIGNUM_SIGN(limit)) { + limit = (struct RBignum *)rb_big_clone(vmax); + RBIGNUM_SET_SIGN(limit, 1); } - if (RFLOAT_VALUE(vmax) < 0) - vmax = rb_dbl2big(-RFLOAT_VALUE(vmax)); - else - vmax = rb_dbl2big(RFLOAT_VALUE(vmax)); - /* fall through */ - case T_BIGNUM: - bignum: - { - struct RBignum *limit = (struct RBignum *)vmax; - if (!RBIGNUM_SIGN(limit)) { - limit = (struct RBignum *)rb_big_clone(vmax); - RBIGNUM_SET_SIGN(limit, 1); - } - limit = (struct RBignum *)rb_big_minus((VALUE)limit, INT2FIX(1)); - if (FIXNUM_P((VALUE)limit)) { - if (FIX2LONG((VALUE)limit) == -1) - return DBL2NUM(genrand_real(mt)); - return LONG2NUM(limited_rand(mt, FIX2LONG((VALUE)limit))); - } - return limited_big_rand(mt, limit); + limit = (struct RBignum *)rb_big_minus((VALUE)limit, INT2FIX(1)); + if (FIXNUM_P((VALUE)limit)) { + if (FIX2LONG((VALUE)limit) == -1) + return DBL2NUM(genrand_real(mt)); + return LONG2NUM(limited_rand(mt, FIX2LONG((VALUE)limit))); } - case T_NIL: - max = 0; - break; - default: - vmax = rb_Integer(vmax); - if (TYPE(vmax) == T_BIGNUM) goto bignum; - case T_FIXNUM: - max = FIX2LONG(vmax); - break; + return limited_big_rand(mt, limit); } + max = NUM2LONG(vmax); if (max == 0) { + zero_arg: return DBL2NUM(genrand_real(mt)); } if (max < 0) max = -max; diff --git a/test/ruby/test_rand.rb b/test/ruby/test_rand.rb index b7d841dbba..7f1e71de3f 100644 --- a/test/ruby/test_rand.rb +++ b/test/ruby/test_rand.rb @@ -144,7 +144,7 @@ class TestRand < Test::Unit::TestCase 0.000000000000001) srand(0) o = Object.new - def o.to_i; 100; end + def o.to_int; 100; end assert_equal(44, rand(o)) assert_equal(47, rand(o)) assert_equal(64, rand(o))