Project

General

Profile

Feature #4605 » random.diff

sorah patch - sorah (Sorah Fukumori), 04/24/2011 10:27 PM

View differences:

random.c
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);
......
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;
}
......
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);
}
}
......
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)) {
......
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);
......
/*
* 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.
......
/*
* call-seq:
* rand(max=0) -> number
* rand(limit) -> number
*
* Converts <i>max</i> to an integer using max1 =
* max<code>.to_i.abs</code>. 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. <code>Kernel::srand</code>
* 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;
    (1-1/1)