summaryrefslogtreecommitdiff
path: root/random.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-29 13:29:12 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-29 13:29:12 +0000
commit6bbd76a73295564871ab06f8da167ce6de0af467 (patch)
treef0539bc7d34396eb61f61579dcd03257f5b01844 /random.c
parentdb86fef72f2a4b54748cd6b7aa656836c3b332af (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21178 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'random.c')
-rw-r--r--random.c52
1 files changed, 17 insertions, 35 deletions
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;