rand(p1 = v1)
public
Converts max to an integer using max1 = max.to_i.abs. If 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.
srand 1234
[ rand, rand ]
[ rand(10), rand(1000) ]
srand 1234
[ rand, rand ]
Show source
static VALUE
rb_f_rand(int argc, VALUE *argv, VALUE obj)
{
VALUE vmax;
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 (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);
}
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;
}
if (max == 0) {
return DBL2NUM(genrand_real(mt));
}
if (max < 0) max = -max;
val = limited_rand(mt, max-1);
return LONG2NUM(val);
}