rand(*args)
public
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)
prng.rand(5...9)
prng.rand(5.0..9.0)
prng.rand(5.0...9.0)
begin/end of the range have to have subtract and add methods.
Otherwise, it raises an ArgumentError.
Show source
static VALUE
random_rand(int argc, VALUE *argv, VALUE obj)
{
rb_random_t *rnd = get_rnd(obj);
VALUE vmax, beg = Qundef, v;
int excl = 0;
if (argc == 0) {
return rb_float_new(genrand_real(&rnd->mt));
}
else if (argc != 1) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
}
vmax = argv[0];
if (NIL_P(vmax)) {
v = Qnil;
}
else if (TYPE(vmax) != T_FLOAT && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
v = rand_int(&rnd->mt, vmax = 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));
else
v = Qnil;
}
else if ((v = range_values(vmax, &beg, &excl)) != Qfalse) {
vmax = v;
if (TYPE(vmax) != T_FLOAT && (v = rb_check_to_integer(vmax, "to_int"), !NIL_P(v))) {
long max;
vmax = v;
v = Qnil;
if (FIXNUM_P(vmax)) {
fixnum:
if ((max = FIX2LONG(vmax) - excl) >= 0) {
unsigned long r = limited_rand(&rnd->mt, (unsigned long)max);
v = ULONG2NUM(r);
}
}
else if (BUILTIN_TYPE(vmax) == T_BIGNUM && RBIGNUM_SIGN(vmax) && !rb_bigzero_p(vmax)) {
vmax = excl ? rb_big_minus(vmax, INT2FIX(1)) : rb_big_norm(vmax);
if (FIXNUM_P(vmax)) {
excl = 0;
goto fixnum;
}
v = limited_big_rand(&rnd->mt, RBIGNUM(vmax));
}
}
else if (v = rb_check_to_float(vmax), !NIL_P(v)) {
double max = float_value(v), r;
v = Qnil;
if (max > 0.0) {
if (excl) {
r = genrand_real(&rnd->mt);
}
else {
r = genrand_real2(&rnd->mt);
}
v = rb_float_new(r * max);
}
else if (max == 0.0 && !excl) {
v = rb_float_new(0.0);
}
}
}
else {
v = Qnil;
NUM2LONG(vmax);
}
if (NIL_P(v)) {
VALUE mesg = rb_str_new_cstr("invalid argument - ");
rb_str_append(mesg, rb_obj_as_string(argv[0]));
rb_exc_raise(rb_exc_new3(rb_eArgError, mesg));
}
if (beg == Qundef) return v;
if (FIXNUM_P(beg) && FIXNUM_P(v)) {
long x = FIX2LONG(beg) + FIX2LONG(v);
return LONG2NUM(x);
}
switch (TYPE(v)) {
case T_BIGNUM:
return rb_big_plus(v, beg);
case T_FLOAT: {
VALUE f = rb_check_to_float(beg);
if (!NIL_P(f)) {
RFLOAT_VALUE(v) += RFLOAT_VALUE(f);
return v;
}
}
default:
return rb_funcall2(beg, id_plus, 1, &v);
}
}