Feature #4605 » random.diff
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;
|