diff --git random.c random.c
index 15a7f51..10c9fe6 100644
--- random.c
+++ random.c
@@ -1025,39 +1025,14 @@ float_value(VALUE v)
return x;
}
-/*
- * call-seq:
- * prng.rand -> float
- * prng.rand(limit) -> number
- *
- * When the argument is an +Integer+ or a +Bignum+, it returns a
- * random integer greater than or equal to zero and less than the
- * argument. Unlike Random.rand, when the argument is a negative
- * integer or zero, it raises an ArgumentError.
- *
- * When the argument is a +Float+, it returns a random floating point
- * number between 0.0 and _max_, including 0.0 and excluding _max_.
- *
- * When the argument _limit_ is a +Range+, it returns a random
- * number where range.member?(number) == true.
- * prng.rand(5..9) #=> one of [5, 6, 7, 8, 9]
- * prng.rand(5...9) #=> one of [5, 6, 7, 8]
- * prng.rand(5.0..9.0) #=> between 5.0 and 9.0, including 9.0
- * prng.rand(5.0...9.0) #=> between 5.0 and 9.0, excluding 9.0
- *
- * +begin+/+end+ of the range have to have subtract and add methods.
- *
- * Otherwise, it raises an ArgumentError.
- */
static VALUE
-random_rand(int argc, VALUE *argv, VALUE obj)
+random_rand_get(int argc, VALUE *argv, struct MT *mt)
{
- rb_random_t *rnd = get_rnd(obj);
VALUE vmax, beg = Qundef, end = Qundef, v;
int excl = 0;
if (argc == 0) {
- return rb_float_new(genrand_real(&rnd->mt));
+ return rb_float_new(genrand_real(mt));
}
else if (argc != 1) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
@@ -1067,12 +1042,12 @@ random_rand(int argc, VALUE *argv, VALUE obj)
v = Qnil;
}
else if (TYPE(vmax) != T_FLOAT && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
- v = rand_int(&rnd->mt, v, 1);
+ v = rand_int(mt, v, 1);
}
else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
double max = float_value(v);
if (max > 0.0)
- v = rb_float_new(max * genrand_real(&rnd->mt));
+ v = rb_float_new(max * genrand_real(mt));
else
v = Qnil;
}
@@ -1085,7 +1060,7 @@ random_rand(int argc, VALUE *argv, VALUE obj)
if (FIXNUM_P(vmax)) {
fixnum:
if ((max = FIX2LONG(vmax) - excl) >= 0) {
- unsigned long r = limited_rand(&rnd->mt, (unsigned long)max);
+ unsigned long r = limited_rand(mt, (unsigned long)max);
v = ULONG2NUM(r);
}
}
@@ -1095,7 +1070,7 @@ random_rand(int argc, VALUE *argv, VALUE obj)
excl = 0;
goto fixnum;
}
- v = limited_big_rand(&rnd->mt, RBIGNUM(vmax));
+ v = limited_big_rand(mt, RBIGNUM(vmax));
}
}
else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
@@ -1114,10 +1089,10 @@ random_rand(int argc, VALUE *argv, VALUE obj)
v = Qnil;
if (max > 0.0) {
if (excl) {
- r = genrand_real(&rnd->mt);
+ r = genrand_real(mt);
}
else {
- r = genrand_real2(&rnd->mt);
+ r = genrand_real2(mt);
}
if (scale > 1) {
return rb_float_new(+(+(+(r - 0.5) * max) * scale) + mid);
@@ -1160,6 +1135,36 @@ random_rand(int argc, VALUE *argv, VALUE obj)
/*
* call-seq:
+ * prng.rand -> float
+ * prng.rand(limit) -> number
+ *
+ * When the argument is an +Integer+ or a +Bignum+, it returns a
+ * random integer greater than or equal to zero and less than the
+ * argument. Unlike Random.rand, when the argument is a negative
+ * integer or zero, it raises an ArgumentError.
+ *
+ * When the argument is a +Float+, it returns a random floating point
+ * number between 0.0 and _max_, including 0.0 and excluding _max_.
+ *
+ * When the argument _limit_ is a +Range+, it returns a random
+ * number where range.member?(number) == true.
+ * prng.rand(5..9) #=> one of [5, 6, 7, 8, 9]
+ * prng.rand(5...9) #=> one of [5, 6, 7, 8]
+ * prng.rand(5.0..9.0) #=> between 5.0 and 9.0, including 9.0
+ * prng.rand(5.0...9.0) #=> between 5.0 and 9.0, excluding 9.0
+ *
+ * +begin+/+end+ of the range have to have subtract and add methods.
+ *
+ * Otherwise, it raises an ArgumentError.
+ */
+static VALUE
+random_rand(int argc, VALUE *argv, VALUE obj)
+{
+ return random_rand_get(argc,argv,&(get_rnd(obj)->mt));
+}
+
+/*
+ * call-seq:
* prng1 == prng2 -> true or false
*
* Returns true if the generators' states equal.
@@ -1180,39 +1185,35 @@ random_equal(VALUE self, VALUE other)
/*
* call-seq:
- * rand(max=0) -> number
+ * rand(limit) -> number
*
- * Converts max to an integer using max1 =
- * max.to_i.abs
. If _max_ is +nil+ the result is zero, returns a
- * pseudorandom floating point number greater than or equal to 0.0 and
- * less than 1.0. Otherwise, returns a pseudorandom integer greater
- * than or equal to zero and less than max1. Kernel::srand
- * may be used to ensure repeatable sequences of random numbers between
- * different runs of the program. Ruby currently uses a modified
- * Mersenne Twister with a period of 2**19937-1.
+ * When the argument is an +Integer+ or a +Bignum+, it returns a
+ * random integer greater than or equal to zero and less than the
+ * argument. Unlike Random.rand, when the argument is a negative
+ * integer or zero, it raises an ArgumentError.
*
- * srand 1234 #=> 0
- * [ rand, rand ] #=> [0.191519450163469, 0.49766366626136]
- * [ rand(10), rand(1000) ] #=> [6, 817]
- * srand 1234 #=> 1234
- * [ rand, rand ] #=> [0.191519450163469, 0.49766366626136]
+ * When the argument _limit_ is a +Range+, it returns a random
+ * number where range.member?(number) == true.
+ * prng.rand(5..9) #=> one of [5, 6, 7, 8, 9]
+ * prng.rand(5...9) #=> one of [5, 6, 7, 8]
+ *
+ * +begin+/+end+ of the range have to have subtract and add methods.
+ *
+ * When the argument is not an +Integer+, a +Bignum+ or a +Range+ and it
+ * can convert to interger, it'll be converted to integer and use as
+ * an +Integer+.
+ *
+ * Otherwise, it raises an ArgumentError.
*/
static VALUE
rb_f_rand(int argc, VALUE *argv, VALUE obj)
{
- VALUE vmax, r;
- struct MT *mt = default_mt();
+ VALUE v;
+ if(argc == 1 && (v = rb_check_to_integer(argv[0], "to_int"), !NIL_P(v)))
+ argv[0] = v;
- 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 (vmax == INT2FIX(0) || NIL_P(r = rand_int(mt, vmax, 0))) {
- zero_arg:
- return DBL2NUM(genrand_real(mt));
- }
- return r;
+ return random_rand_get(argc,argv,default_mt());
}
static st_index_t hashseed;