mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* random.c (random_rand): unified random_int and random_float.
[ruby-dev:39158]. and fixes [ruby-core:24655], [ruby-core:24677], [ruby-core:24679]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24670 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
47a1a7b67d
commit
9676023607
5 changed files with 223 additions and 116 deletions
|
@ -1,3 +1,9 @@
|
|||
Wed Aug 26 19:20:26 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* random.c (random_rand): unified random_int and random_float.
|
||||
[ruby-dev:39158]. and fixes [ruby-core:24655], [ruby-core:24677],
|
||||
[ruby-core:24679].
|
||||
|
||||
Wed Aug 26 18:59:59 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* test/test_tempfile.rb: merged from Hongli Lai's fork.
|
||||
|
|
|
@ -466,6 +466,7 @@ VALUE rb_class_inherited_p(VALUE, VALUE);
|
|||
VALUE rb_convert_type(VALUE,int,const char*,const char*);
|
||||
VALUE rb_check_convert_type(VALUE,int,const char*,const char*);
|
||||
VALUE rb_check_to_integer(VALUE, const char *);
|
||||
VALUE rb_check_to_float(VALUE);
|
||||
VALUE rb_to_int(VALUE);
|
||||
VALUE rb_Integer(VALUE);
|
||||
VALUE rb_to_float(VALUE);
|
||||
|
|
10
object.c
10
object.c
|
@ -2299,6 +2299,16 @@ rb_to_float(VALUE val)
|
|||
return rb_convert_type(val, T_FLOAT, "Float", "to_f");
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_check_to_float(VALUE val)
|
||||
{
|
||||
if (TYPE(val) == T_FLOAT) return val;
|
||||
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
|
||||
return Qnil;
|
||||
}
|
||||
return rb_check_convert_type(val, T_FLOAT, "Float", "to_f");
|
||||
}
|
||||
|
||||
double
|
||||
rb_num2dbl(VALUE val)
|
||||
{
|
||||
|
|
228
random.c
228
random.c
|
@ -178,6 +178,16 @@ genrand_real(struct MT *mt)
|
|||
unsigned int a = genrand_int32(mt)>>5, b = genrand_int32(mt)>>6;
|
||||
return(a*67108864.0+b)*(1.0/9007199254740992.0);
|
||||
}
|
||||
|
||||
/* generates a random number on [0,1] with 53-bit resolution*/
|
||||
static double int_pair_to_real_inclusive(unsigned int a, unsigned int b);
|
||||
static double
|
||||
genrand_real2(struct MT *mt)
|
||||
{
|
||||
unsigned int a = genrand_int32(mt), b = genrand_int32(mt);
|
||||
return int_pair_to_real_inclusive(a, b);
|
||||
}
|
||||
|
||||
/* These real versions are due to Isaku Wada, 2002/01/09 added */
|
||||
|
||||
#undef N
|
||||
|
@ -238,6 +248,57 @@ rb_genrand_real(void)
|
|||
#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
|
||||
#define SIZEOF_INT32 (31/CHAR_BIT + 1)
|
||||
|
||||
static double
|
||||
int_pair_to_real_inclusive(unsigned int a, unsigned int b)
|
||||
{
|
||||
VALUE x = rb_big_new(roomof(64, BITSPERDIG), 1);
|
||||
VALUE m = rb_big_new(roomof(53, BITSPERDIG), 1);
|
||||
BDIGIT *xd = BDIGITS(x);
|
||||
int i = 0;
|
||||
double r;
|
||||
|
||||
xd[i++] = (BDIGIT)b;
|
||||
#if BITSPERDIG < 32
|
||||
xd[i++] = (BDIGIT)(b >> BITSPERDIG);
|
||||
#endif
|
||||
xd[i++] = (BDIGIT)a;
|
||||
#if BITSPERDIG < 32
|
||||
xd[i++] = (BDIGIT)(a >> BITSPERDIG);
|
||||
#endif
|
||||
xd = BDIGITS(m);
|
||||
#if BITSPERDIG < 53
|
||||
MEMZERO(xd, BDIGIT, roomof(53, BITSPERDIG) - 1);
|
||||
#endif
|
||||
xd[53 / BITSPERDIG] = 1 << 53 % BITSPERDIG;
|
||||
xd[0] |= 1;
|
||||
x = rb_big_mul(x, m);
|
||||
if (FIXNUM_P(x)) {
|
||||
#if CHAR_BIT * SIZEOF_LONG > 64
|
||||
r = (double)(FIX2ULONG(x) >> 64);
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#if 64 % BITSPERDIG == 0
|
||||
long len = RBIGNUM_LEN(x);
|
||||
xd = BDIGITS(x);
|
||||
MEMMOVE(xd, xd + 64 / BITSPERDIG, BDIGIT, len - 64 / BITSPERDIG);
|
||||
MEMZERO(xd + len - 64 / BITSPERDIG, BDIGIT, 64 / BITSPERDIG);
|
||||
r = rb_big2dbl(x);
|
||||
#else
|
||||
x = rb_big_rshift(x, INT2FIX(64));
|
||||
if (FIXNUM_P(x)) {
|
||||
r = (double)FIX2ULONG(x);
|
||||
}
|
||||
else {
|
||||
r = rb_big2dbl(x);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ldexp(r, -53);
|
||||
}
|
||||
|
||||
VALUE rb_cRandom;
|
||||
#define id_minus '-'
|
||||
#define id_plus '+'
|
||||
|
@ -829,19 +890,14 @@ rb_random_bytes(VALUE obj, long n)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
range_values(VALUE vmax, VALUE *begp)
|
||||
range_values(VALUE vmax, VALUE *begp, int *exclp)
|
||||
{
|
||||
VALUE end, r, one = INT2FIX(1);
|
||||
int excl;
|
||||
VALUE end, r;
|
||||
|
||||
if (!rb_range_values(vmax, begp, &end, &excl)) return Qfalse;
|
||||
if (!rb_range_values(vmax, begp, &end, exclp)) return Qfalse;
|
||||
if (!rb_respond_to(end, id_minus)) return Qfalse;
|
||||
r = rb_funcall2(end, id_minus, 1, begp);
|
||||
if (NIL_P(r)) return Qfalse;
|
||||
if (!excl && rb_respond_to(r, id_plus)) {
|
||||
r = rb_funcall2(r, id_plus, 1, &one);
|
||||
if (NIL_P(r)) return Qfalse;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -853,7 +909,7 @@ add_to_begin(VALUE beg, VALUE offset)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rand_int(struct MT *mt, VALUE vmax)
|
||||
rand_int(struct MT *mt, VALUE vmax, int restrictive)
|
||||
{
|
||||
long max;
|
||||
unsigned long r;
|
||||
|
@ -861,13 +917,18 @@ rand_int(struct MT *mt, VALUE vmax)
|
|||
if (FIXNUM_P(vmax)) {
|
||||
max = FIX2LONG(vmax);
|
||||
if (!max) return Qnil;
|
||||
r = limited_rand(mt, (unsigned long)(max < 0 ? -max : max) - 1);
|
||||
if (max < 0) {
|
||||
if (restrictive) return Qnil;
|
||||
max = -max;
|
||||
}
|
||||
r = limited_rand(mt, (unsigned long)max - 1);
|
||||
return ULONG2NUM(r);
|
||||
}
|
||||
else {
|
||||
VALUE ret;
|
||||
if (rb_bigzero_p(vmax)) return Qnil;
|
||||
if (!RBIGNUM_SIGN(vmax)) {
|
||||
if (restrictive) return Qnil;
|
||||
vmax = rb_big_clone(vmax);
|
||||
RBIGNUM_SET_SIGN(vmax, 1);
|
||||
}
|
||||
|
@ -884,86 +945,110 @@ rand_int(struct MT *mt, VALUE vmax)
|
|||
}
|
||||
}
|
||||
|
||||
static inline double
|
||||
float_value(VALUE v)
|
||||
{
|
||||
double x = RFLOAT_VALUE(v);
|
||||
if (isinf(x) || isnan(x)) {
|
||||
VALUE error = INT2FIX(EDOM);
|
||||
rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq: prng.int(limit) -> integer
|
||||
* 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
|
||||
* integer from integers where range.member?(integer) == true.
|
||||
* prng.int(5..9) # => one of [5, 6, 7, 8, 9]
|
||||
* prng.int(5...9) # => one of [5, 6, 7, 8]
|
||||
* 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 subtruct and add methods.
|
||||
*
|
||||
* Otherwise, it raises an ArgumentError.
|
||||
*/
|
||||
VALUE
|
||||
rb_random_int(VALUE obj, VALUE vmax)
|
||||
{
|
||||
VALUE v, beg = Qundef;
|
||||
rb_random_t *rnd = get_rnd(obj);
|
||||
|
||||
v = rb_check_to_integer(vmax, "to_int");
|
||||
if (NIL_P(v)) {
|
||||
/* range like object support */
|
||||
if (!(v = range_values(vmax, &beg))) {
|
||||
v = vmax;
|
||||
}
|
||||
v = rb_to_int(v);
|
||||
beg = rb_to_int(beg);
|
||||
}
|
||||
v = rand_int(&rnd->mt, v);
|
||||
if (NIL_P(v)) v = INT2FIX(0);
|
||||
return add_to_begin(beg, v);
|
||||
}
|
||||
|
||||
#define random_int rb_random_int
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* prng.float -> float
|
||||
* prng.float([max=1.0]) -> float
|
||||
*
|
||||
* Returns a random floating point number between 0.0 and _max_,
|
||||
* including 0.0 and excluding _max_.
|
||||
*/
|
||||
static VALUE
|
||||
random_float(int argc, VALUE *argv, VALUE obj)
|
||||
random_rand(int argc, VALUE *argv, VALUE obj)
|
||||
{
|
||||
rb_random_t *rnd = get_rnd(obj);
|
||||
VALUE vmax, beg = Qundef;
|
||||
double max = 0, r;
|
||||
VALUE vmax, beg = Qundef, v;
|
||||
int excl = 0;
|
||||
|
||||
switch (argc) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
vmax = argv[0];
|
||||
if (TYPE(vmax) == T_FLOAT ||
|
||||
!NIL_P(vmax = rb_to_float(vmax)) ||
|
||||
(vmax = range_values(vmax, &beg)) != Qfalse) {
|
||||
max = RFLOAT_VALUE(vmax);
|
||||
if (isinf(max) || isnan(max)) {
|
||||
VALUE error = INT2FIX(EDOM);
|
||||
rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
|
||||
if (argc == 0) {
|
||||
zero_arg:
|
||||
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)) {
|
||||
goto zero_arg;
|
||||
}
|
||||
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 {
|
||||
beg = Qundef;
|
||||
Check_Type(argv[0], T_FLOAT);
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rb_scan_args(argc, argv, "01", 0);
|
||||
break;
|
||||
}
|
||||
r = genrand_real(&rnd->mt);
|
||||
if (argc) r *= max;
|
||||
return add_to_begin(beg, rb_float_new(r));
|
||||
else {
|
||||
NUM2LONG(vmax);
|
||||
}
|
||||
if (NIL_P(v)) rb_raise(rb_eArgError, "invalid argument");
|
||||
return add_to_begin(beg, v);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1019,7 +1104,7 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
|
|||
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))) {
|
||||
if (vmax == INT2FIX(0) || NIL_P(r = rand_int(mt, vmax, 0))) {
|
||||
zero_arg:
|
||||
return DBL2NUM(genrand_real(mt));
|
||||
}
|
||||
|
@ -1058,9 +1143,8 @@ Init_Random(void)
|
|||
rb_cRandom = rb_define_class("Random", rb_cObject);
|
||||
rb_define_alloc_func(rb_cRandom, random_alloc);
|
||||
rb_define_method(rb_cRandom, "initialize", random_init, -1);
|
||||
rb_define_method(rb_cRandom, "int", random_int, 1);
|
||||
rb_define_method(rb_cRandom, "rand", random_rand, -1);
|
||||
rb_define_method(rb_cRandom, "bytes", random_bytes, 1);
|
||||
rb_define_method(rb_cRandom, "float", random_float, -1);
|
||||
rb_define_method(rb_cRandom, "seed", random_get_seed, 0);
|
||||
rb_define_method(rb_cRandom, "initialize_copy", random_copy, 1);
|
||||
rb_define_method(rb_cRandom, "marshal_dump", random_dump, 0);
|
||||
|
|
|
@ -10,14 +10,14 @@ class TestRand < Test::Unit::TestCase
|
|||
w = w.to_i
|
||||
assert_equal(w, rand(m))
|
||||
rnds.each do |rnd|
|
||||
assert_equal(w, rnd.int(m))
|
||||
assert_equal(w, rnd.rand(m))
|
||||
end
|
||||
rnds2.each do |rnd|
|
||||
r=rnd.int(i...(m+i))
|
||||
r=rnd.rand(i...(m+i))
|
||||
assert_equal(w+i, r)
|
||||
end
|
||||
rnds3.each do |rnd|
|
||||
r=rnd.int(i..(m+i-1))
|
||||
r=rnd.rand(i..(m+i-1))
|
||||
assert_equal(w+i, r)
|
||||
end
|
||||
rnds << Marshal.load(Marshal.dump(rnds[-1]))
|
||||
|
@ -110,64 +110,61 @@ class TestRand < Test::Unit::TestCase
|
|||
0x4000000000000001)
|
||||
end
|
||||
|
||||
def test_neg_0x10000000000
|
||||
def test_0x10000000000
|
||||
ws = %w(455570294424 1073054410371 790795084744 2445173525 1088503892627)
|
||||
assert_random_int(ws, 0x10000000000, 3)
|
||||
assert_random_int(ws, -0x10000000000, 3)
|
||||
end
|
||||
|
||||
def test_neg_0x10000
|
||||
def test_0x10000
|
||||
ws = %w(2732 43567 42613 52416 45891)
|
||||
assert_random_int(ws, 0x10000)
|
||||
assert_random_int(ws, -0x10000)
|
||||
end
|
||||
|
||||
def test_types
|
||||
srand(0)
|
||||
rnd = Random.new(0)
|
||||
assert_equal(44, rand(100.0))
|
||||
assert_equal(44, rnd.int(100.0))
|
||||
assert_equal(44, rnd.rand(100))
|
||||
assert_equal(1245085576965981900420779258691, rand((2**100).to_f))
|
||||
assert_equal(1245085576965981900420779258691, rnd.int((2**100).to_f))
|
||||
assert_equal(1245085576965981900420779258691, rnd.rand(2**100))
|
||||
assert_equal(914679880601515615685077935113, rand(-(2**100).to_f))
|
||||
assert_equal(914679880601515615685077935113, rnd.int(-(2**100).to_f))
|
||||
|
||||
srand(0)
|
||||
rnd = Random.new(0)
|
||||
assert_equal(997707939797331598305742933184, rand(2**100))
|
||||
assert_equal(997707939797331598305742933184, rnd.int(2**100))
|
||||
assert_equal(997707939797331598305742933184, rnd.rand(2**100))
|
||||
assert_in_delta(0.602763376071644, rand((2**100).coerce(0).first),
|
||||
0.000000000000001)
|
||||
assert_equal(0, rnd.int((2**100).coerce(0).first))
|
||||
assert_raise(ArgumentError) {rnd.rand((2**100).coerce(0).first)}
|
||||
|
||||
srand(0)
|
||||
rnd = Random.new(0)
|
||||
assert_in_delta(0.548813503927325, rand(nil),
|
||||
0.000000000000001)
|
||||
assert_in_delta(0.548813503927325, rnd.float(),
|
||||
assert_in_delta(0.548813503927325, rnd.rand(),
|
||||
0.000000000000001)
|
||||
srand(0)
|
||||
rnd = Random.new(0)
|
||||
o = Object.new
|
||||
def o.to_int; 100; end
|
||||
assert_equal(44, rand(o))
|
||||
assert_equal(44, rnd.int(o))
|
||||
assert_equal(44, rnd.rand(o))
|
||||
assert_equal(47, rand(o))
|
||||
assert_equal(47, rnd.int(o))
|
||||
assert_equal(47, rnd.rand(o))
|
||||
assert_equal(64, rand(o))
|
||||
assert_equal(64, rnd.int(o))
|
||||
assert_equal(64, rnd.rand(o))
|
||||
end
|
||||
|
||||
def test_srand
|
||||
srand
|
||||
assert_kind_of(Integer, rand(2))
|
||||
assert_kind_of(Integer, Random.new.int(2))
|
||||
assert_kind_of(Integer, Random.new.rand(2))
|
||||
|
||||
srand(2**100)
|
||||
rnd = Random.new(2**100)
|
||||
%w(3258412053).each {|w|
|
||||
assert_equal(w.to_i, rand(0x100000000))
|
||||
assert_equal(w.to_i, rnd.int(0x100000000))
|
||||
assert_equal(w.to_i, rnd.rand(0x100000000))
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -183,21 +180,25 @@ class TestRand < Test::Unit::TestCase
|
|||
def test_random_gc
|
||||
r = Random.new(0)
|
||||
%w(2357136044 2546248239 3071714933).each do |w|
|
||||
assert_equal(w.to_i, r.int(0x100000000))
|
||||
assert_equal(w.to_i, r.rand(0x100000000))
|
||||
end
|
||||
GC.start
|
||||
%w(3626093760 2588848963 3684848379).each do |w|
|
||||
assert_equal(w.to_i, r.int(0x100000000))
|
||||
assert_equal(w.to_i, r.rand(0x100000000))
|
||||
end
|
||||
end
|
||||
|
||||
def test_random_type_error
|
||||
assert_raise(TypeError) { Random.new(Object.new) }
|
||||
assert_raise(TypeError) { Random.new(0).int(Object.new) }
|
||||
assert_raise(TypeError) { Random.new(0).rand(Object.new) }
|
||||
end
|
||||
|
||||
def test_random_argument_error
|
||||
assert_raise(ArgumentError) { Random.new(0).float(0, 0) }
|
||||
r = Random.new(0)
|
||||
assert_raise(ArgumentError) { r.rand(0, 0) }
|
||||
assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(-1) }
|
||||
assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(-1.0) }
|
||||
assert_raise(ArgumentError, '[ruby-core:24677]') { r.rand(0) }
|
||||
end
|
||||
|
||||
def test_random_seed
|
||||
|
@ -210,17 +211,17 @@ class TestRand < Test::Unit::TestCase
|
|||
r1 = Random.new(0)
|
||||
r2 = r1.dup
|
||||
%w(2357136044 2546248239 3071714933).each do |w|
|
||||
assert_equal(w.to_i, r1.int(0x100000000))
|
||||
assert_equal(w.to_i, r1.rand(0x100000000))
|
||||
end
|
||||
%w(2357136044 2546248239 3071714933).each do |w|
|
||||
assert_equal(w.to_i, r2.int(0x100000000))
|
||||
assert_equal(w.to_i, r2.rand(0x100000000))
|
||||
end
|
||||
r2 = r1.dup
|
||||
%w(3626093760 2588848963 3684848379).each do |w|
|
||||
assert_equal(w.to_i, r1.int(0x100000000))
|
||||
assert_equal(w.to_i, r1.rand(0x100000000))
|
||||
end
|
||||
%w(3626093760 2588848963 3684848379).each do |w|
|
||||
assert_equal(w.to_i, r2.int(0x100000000))
|
||||
assert_equal(w.to_i, r2.rand(0x100000000))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -309,16 +310,16 @@ END
|
|||
srand(0)
|
||||
assert_equal(state, r.instance_eval { state })
|
||||
assert_equal(state, Random.instance_eval { state })
|
||||
r.int(0x100)
|
||||
r.rand(0x100)
|
||||
assert_equal(state, r.instance_eval { state })
|
||||
end
|
||||
|
||||
def test_random_left
|
||||
r = Random.new(0)
|
||||
assert_equal(1, r.instance_eval { left })
|
||||
r.int(0x100)
|
||||
r.rand(0x100)
|
||||
assert_equal(624, r.instance_eval { left })
|
||||
r.int(0x100)
|
||||
r.rand(0x100)
|
||||
assert_equal(623, r.instance_eval { left })
|
||||
srand(0)
|
||||
assert_equal(1, Random.instance_eval { left })
|
||||
|
@ -337,29 +338,34 @@ END
|
|||
|
||||
def test_random_range
|
||||
r = Random.new(0)
|
||||
%w(9 5 8).each {|w| assert_equal(w.to_i, r.int(5..9)) }
|
||||
%w(-237 731 383).each {|w| assert_equal(w.to_i, r.int(-1000..1000)) }
|
||||
%w(9 5 8).each {|w| assert_equal(w.to_i, r.rand(5..9)) }
|
||||
%w(-237 731 383).each {|w| assert_equal(w.to_i, r.rand(-1000..1000)) }
|
||||
%w(1267650600228229401496703205382
|
||||
1267650600228229401496703205384
|
||||
1267650600228229401496703205383).each do |w|
|
||||
assert_equal(w.to_i, r.int(2**100+5..2**100+9))
|
||||
assert_equal(w.to_i, r.rand(2**100+5..2**100+9))
|
||||
end
|
||||
assert_equal(3, r.int(3.1..4), '[ruby-core:24679]')
|
||||
v = r.rand(3.1..4)
|
||||
assert_instance_of(Float, v, '[ruby-core:24679]')
|
||||
assert_includes(3.1..4, v)
|
||||
end
|
||||
|
||||
def test_random_float
|
||||
r = Random.new(0)
|
||||
assert_in_delta(0.5488135039273248, r.float, 0.0001)
|
||||
assert_in_delta(0.7151893663724195, r.float, 0.0001)
|
||||
assert_in_delta(0.6027633760716439, r.float, 0.0001)
|
||||
assert_in_delta(1.0897663659937937, r.float(2), 0.0001)
|
||||
assert_in_delta(5.3704626067153264e+29, r.float(2**100), 10**25)
|
||||
assert_in_delta(0.5488135039273248, r.rand, 0.0001)
|
||||
assert_in_delta(0.7151893663724195, r.rand, 0.0001)
|
||||
assert_in_delta(0.6027633760716439, r.rand, 0.0001)
|
||||
assert_in_delta(1.0897663659937937, r.rand(2.0), 0.0001)
|
||||
assert_in_delta(5.3704626067153264e+29, r.rand((2**100).to_f), 10**25)
|
||||
|
||||
assert_raise(Errno::EDOM, Errno::ERANGE) { r.float(1.0 / 0.0) }
|
||||
assert_raise(Errno::EDOM, Errno::ERANGE) { r.float(0.0 / 0.0) }
|
||||
assert_raise(Errno::EDOM, Errno::ERANGE) { r.rand(1.0 / 0.0) }
|
||||
assert_raise(Errno::EDOM, Errno::ERANGE) { r.rand(0.0 / 0.0) }
|
||||
|
||||
# is this intentional?
|
||||
assert_raise(TypeError) { r.float(1..2) }
|
||||
r = Random.new(0)
|
||||
assert_in_delta(1.5488135039273248, r.rand(1.0...2.0), 0.0001, '[ruby-core:24655]')
|
||||
assert_in_delta(1.7151893663724195, r.rand(1.0...2.0), 0.0001, '[ruby-core:24655]')
|
||||
assert_in_delta(7.027633760716439, r.rand(1.0...11.0), 0.0001, '[ruby-core:24655]')
|
||||
assert_in_delta(3.0897663659937937, r.rand(2.0...4.0), 0.0001, '[ruby-core:24655]')
|
||||
end
|
||||
|
||||
def test_random_equal
|
||||
|
@ -368,9 +374,9 @@ END
|
|||
assert(r == r.dup)
|
||||
r1 = r.dup
|
||||
r2 = r.dup
|
||||
r1.int(0x100)
|
||||
r1.rand(0x100)
|
||||
assert(r1 != r2)
|
||||
r2.int(0x100)
|
||||
r2.rand(0x100)
|
||||
assert(r1 == r2)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue