# Random#rand

**URL:** <https://www.ruby-forum.com/t/random-rand/174345>\
**Category:** Development\
**Created:** [August 25, 2009, 11:23am UTC](https://www.ruby-forum.com/t/random-rand/174345 "2009-08-25T11:23:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [August 25, 2009, 11:23am UTC](https://www.ruby-forum.com/t/random-rand/174345/1 "2009-08-25T11:23:58Z")

</div>

e$B$J$+$@$G$9!#e(B

e$B:#$Ne(Btrunke$B$K$O!";n83E\*$Ke(BRandome$B%/%i%9$,$"$j$^$9!#$3$l$K$Oe(Binte$B$He(B  
floate$B$H$$$&%a%=%C%I$,$"$j$^$9$,!"e(BKernel#rande$B$H$N8\_49@-$K7g$1$F$$e(B  
e$B$?$j!“e(BRangee$B$KBP$9$kF0:n$,$o$+$j$K$/$+$C$?$j$7$^$9!#$=$3$Ge(B  
Random#rande$B$KE}9g$7$?$$$H;W$&$N$G$9$,!”$$$+$,$G$7$g$&$+!#e(B

r = Random.new  
r.rand #=\> a float in 0.0…1.0  
r.rand(max\_num) #=\> a number in 0.0…max\_num  
r.rand(range) #=\> a number in range

e$B0z?t$,M?$($i$l$?\>l9g$O7k2L$N%/%i%9$O0z?t$N%/%i%9$K=\>$$$^$9!#e(B  
Rangee$B$N\>l9g$ON\>C\<$NCM$N:9$r;H$$$^$9!#e(B

e$B$?$@$7!"0J2\<$N%Q%C%A$GBP1~$7$F$$$k$N$Oe(BIntegere$B$He(BFloate$B$N$\_$G!"e(B  
Complexe$B$de(BRationale$B$O07$$$^$;$s!#0lBN$I$&$$$&$b$N$,4|BT$5$l$k$N$+e(B  
e$B8+Ev$,$D$+$J$$$N$G!#e(B

# Index: object.c

— object.c (revision 24648)  
+++ object.c (working copy)  
@@ -2300,4 +2300,14 @@ rb\_to\_float(VALUE val)  
}

+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) Index: random.c

— random.c (revision 24648)  
+++ random.c (working copy)  
@@ -179,4 +179,14 @@ genrand\_real(struct MT _mt)  
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 \*/

@@ -239,4 +249,55 @@ rb\_genrand\_real(void)  
#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 ‘-’  
@@ -830,17 +891,12 @@ 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®) return Qfalse;

- if (!excl && rb\_respond\_to(r, id\_plus)) {
- r = rb\_funcall2(r, id\_plus, 1, &one);
- if (NIL\_P®) return Qfalse;
- }  
return r;  
}  
@@ -854,5 +910,5 @@ 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;  
@@ -862,5 +918,12 @@ rand\_int(struct MT \*mt, VALUE 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;

```

- }
- else if (max == 1 && restrictive) {
- 

```
 return Qnil;

```

- }
- r = limited\_rand(mt, (unsigned long)max - 1);  
return ULONG2NUM®;  
}  
@@ -869,4 +932,5 @@ rand\_int(struct MT \*mt, VALUE vmax)  
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);

```

@@ -876,4 +940,5 @@ rand\_int(struct MT \*mt, VALUE vmax)  
max = FIX2LONG(vmax);  
if (max == -1) return Qnil;

- 

```
 if (max == 0 && restrictive) return Qnil;
 r = limited_rand(mt, max);
 return LONG2NUM(r);

```

@@ -885,6 +950,19 @@ 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  
@@ -893,8 +971,13 @@ rand\_int(struct MT \*mt, VALUE vmax)
  - 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.  
@@ -902,67 +985,71 @@ rand\_int(struct MT \*mt, VALUE vmax)
  - 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)  
{

- VALUE rb\_check\_to\_float(VALUE);  
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);
- v = rb\_float\_new(max \* genrand\_real(&rnd-\>mt));
- }
- 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®);

- else {
- NUM2LONG(vmax);
- }
- if (NIL\_P(v)) rb\_raise(rb\_eArgError, “invalid argument”);
- return add\_to\_begin(beg, v);  
}

@@ -1020,5 +1107,5 @@ rb\_f\_rand(int argc, VALUE \*argv, VALUE o  
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));  
@@ -1059,7 +1146,6 @@ Init\_Random(void)  
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);  
Index: test/ruby/test\_rand.rb  
===================================================================  
— test/ruby/test\_rand.rb (revision 24648)  
+++ test/ruby/test\_rand.rb (working copy)  
@@ -11,12 +11,12 @@ class TestRand \< Test::Unit::TestCase  
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

```

@@ -111,14 +111,12 @@ class TestRand \< Test::Unit::TestCase  
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

@@ -127,17 +125,16 @@ class TestRand \< Test::Unit::TestCase  
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))

- 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)}

- assert\_in\_delta(0.548813503927325, rnd.float(),

- assert\_in\_delta(0.548813503927325, rnd.rand(),  
0.000000000000001)  
srand(0)  
@@ -152,9 +149,9 @@ class TestRand \< Test::Unit::TestCase  
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

@@ -162,5 +159,5 @@ class TestRand \< Test::Unit::TestCase  
srand  
assert\_kind\_of(Integer, rand(2))

- assert\_kind\_of(Integer, Random.new.int(2))

- assert\_kind\_of(Integer, Random.new.rand(2))

- 

```
 assert_equal(w.to_i, rnd.int(0x100000000))

```

- 

```
 assert_equal(w.to_i, rnd.rand(0x100000000))

```

}  
end  
@@ -184,9 +181,9 @@ class TestRand \< Test::Unit::TestCase  
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  
@@ -194,9 +191,9 @@ class TestRand \< Test::Unit::TestCase  
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) }

- assert\_raise(ArgumentError) { Random.new(0).rand(0, 0) }  
end

@@ -211,15 +208,15 @@ class TestRand \< Test::Unit::TestCase  
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  
@@ -310,5 +307,5 @@ END  
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  
@@ -317,7 +314,7 @@ END  
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)  
@@ -338,27 +335,26 @@ 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) }
- 
- 
# is this intentional?
- assert\_raise(TypeError) { r.float(1…2) }

- assert\_raise(Errno::EDOM, Errno::ERANGE) { r.rand(1.0 / 0.0) }
- assert\_raise(Errno::EDOM, Errno::ERANGE) { r.rand(0.0 / 0.0) }  
end

@@ -369,7 +365,7 @@ END  
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

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [August 26, 2009, 5:43pm UTC](https://www.ruby-forum.com/t/random-rand/174345/2 "2009-08-26T17:43:53Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:39158] Random#rand”  
on Tue, 25 Aug 2009 18:23:11 +0900, Nobuyoshi N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

|e$B:#$Ne(Btrunke$B$K$O!“;n83E\*$Ke(BRandome$B%/%i%9$,$”$j$^$9!#$3$l$K$Oe(Binte$B$He(B  
|floate$B$H$$$&%a%=%C%I$,$"$j$^$9$,!"e(BKernel#rande$B$H$N8\_49@-$K7g$1$F$$e(B  
|e$B$?$j!“e(BRangee$B$KBP$9$kF0:n$,$o$+$j$K$/$+$C$?$j$7$^$9!#$=$3$Ge(B  
|Random#rande$B$KE}9g$7$?$$$H;W$&$N$G$9$,!”$$$+$,$G$7$g$&$+!#e(B

e$B$$$$$s$8$c$J$$$G$7$g$&$+!#E}9g$9$k$H8@$&$3$H$Oe(Binte$B$He(Bfloate$B$O:oe(B  
e$B=|$H$$$&$3$H$G$7$g$&$+!#e(B

---

<div class="post-metadata">

**Author:** ![nobu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/e9c0ed/32.png) [@nobu](https://www.ruby-forum.com/u/nobu)\
**Post date:** [August 26, 2009, 7:07pm UTC](https://www.ruby-forum.com/t/random-rand/174345/3 "2009-08-26T19:07:42Z")

</div>

e$B@\>;3OB9-$G$9!#e(B

At Tue, 25 Aug 2009 18:23:11 +0900,  
Nobuyoshi N. wrote:

> r = Random.new  
> r.rand #=\> a float in 0.0…1.0  
> r.rand(max\_num) #=\> a number in 0.0…max\_num  
> r.rand(range) #=\> a number in range
> 
> e$B0z?t$,M?$($i$l$?\>l9g$O7k2L$N%/%i%9$O0z?t$N%/%i%9$K=\>$$$^$9!#e(B  
> Rangee$B$N\>l9g$ON\>C\<$NCM$N:9$r;H$$$^$9!#e(B

Random#rand(1) e$B$He(B Random#rand(0…1)  
e$B$N5sF0$,0c$&$N$O0U?^$7$?5sF0$G$7$g$&$+e(B?  
e$B%(%i!\<%a%C%;!\<%8$,!Ve(Binvalid  
argumente$B!W$@$1$J$N$b$o$+$j$K$/$$$h$&$Ke(B  
e$B;W$$$^$9!#e(B

% ruby-trunk -e ‘p Random.new.rand(1)’  
0  
% ruby-trunk -e ‘p Random.new.rand(0…1)’  
-e:1:in `rand': invalid argument (ArgumentError) from -e:1:in`’  
%

e$B0J2\<$N$h$&$KJQ99$9$k$HF1$85sF0$K$J$j$^$7$?!#e(B

diff --git a/random.c b/random.c  
index 3b5729f…9bd2c48 100644  
— a/random.c  
+++ b/random.c  
@@ -1016,7 +1016,7 @@ random\_rand(int argc, VALUE \*argv, VALUE obj)  
v = Qnil;  
if (FIXNUM\_P(vmax)) {  
fixnum:

- if ((max = FIX2LONG(vmax) - excl) \> 0) {

- if ((max = FIX2LONG(vmax) - excl) \>= 0) {  
unsigned long r = limited\_rand(&rnd-\>mt, (unsigned long)max);  
v = ULONG2NUM®;  
}
