Rand random. You've got to be kidding

Surely it must be possible to initialize rand with current date and
time.
Documents seem to indicate this is done with rand(0) or srand with no
value. I
have tried both methods and I get the same tired old sequence of
numbers. I
would write my own random number generator except I don’t know how to
get a
numeric value out of Time.

Charles G.

I haven’t played with rand, but

Time.now.to_i

should get you a useful seed value.

-jro

On 11/28/06, [email protected] [email protected] wrote:

Surely it must be possible to initialize rand with current date and time.
Documents seem to indicate this is done with rand(0) or srand with no value. I
have tried both methods and I get the same tired old sequence of numbers. I
would write my own random number generator except I don’t know how to get a
numeric value out of Time.

Can you post the code that isn’t working for you?

http://www.rubycentral.com/ref/ref_m_kernel.html#rand
http://www.rubycentral.com/ref/ref_m_kernel.html#srand

ruby -e ‘print “#{rand}\t#{rand}\t#{rand}\n”’
0.346093491828657 0.0992270243895501 0.491676115802907
ruby -e ‘print “#{rand}\t#{rand}\t#{rand}\n”’
0.11466702118189 0.0119319523512537 0.111031191235015
ruby -e ‘print “#{rand}\t#{rand}\t#{rand}\n”’
0.282694845926778 0.570101702949362 0.303077309354919

ruby -e ‘srand(1); print “#{rand}\t#{rand}\t#{rand}\n”’
0.417022004702574 0.720324493442158 0.000114374817344887
ruby -e ‘srand(1); print “#{rand}\t#{rand}\t#{rand}\n”’
0.417022004702574 0.720324493442158 0.000114374817344887
ruby -e ‘srand(1); print “#{rand}\t#{rand}\t#{rand}\n”’
0.417022004702574 0.720324493442158 0.000114374817344887

ruby -e ‘srand(2); print “#{rand}\t#{rand}\t#{rand}\n”’
0.435994902142004 0.0259262318278913 0.549662477878709
ruby -e ‘srand(2); print “#{rand}\t#{rand}\t#{rand}\n”’
0.435994902142004 0.0259262318278913 0.549662477878709
ruby -e ‘srand(2); print “#{rand}\t#{rand}\t#{rand}\n”’
0.435994902142004 0.0259262318278913 0.549662477878709

ruby -v
ruby 1.8.4 (2005-12-24) [i586-linux]

On 11/28/06, [email protected] [email protected] wrote:

Surely it must be possible to initialize rand with current date and
time. Documents seem to indicate this is done with rand(0) or srand
with no value. I have tried both methods and I get the same tired old
sequence of numbers. I would write my own random number generator
except I don’t know how to get a numeric value out of Time.

I’m not sure which documents you’re reading. These are the ri docs I
see (examples elided for brevity):

------------------------------------------------------------ Kernel#rand
rand(max=0) => number

 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
 219937-1.

----------------------------------------------------------- Kernel#srand
srand(number=0) => old_seed

 Seeds the pseudorandom number generator to the value of
 _number_.+to_i.abs+. If _number_ is omitted or zero, seeds the
 generator using a combination of the time, the process id, and a
 sequence number. (This is also the behavior if +Kernel::rand+ is
 called without previously calling +srand+, but without the
 sequence.) By setting the seed to a known value, scripts can be
 made deterministic during testing. The previous seed value is
 returned. Also see +Kernel::rand+.

So no, providing an argument to Kernel#rand does not set the seed, it
provides the range. Kernel#srand is used for setting the seed value.
As you indicated, calling Kernel#srand with no argument should reset
the seed to a value based on the current time (+ process id and
sequence number).

However, you should not even need to call Kernel#srand to set the seed
to the current time unless you’ve already reseeded to something else
first. When the Ruby interpreter starts up Kernel#srand is
(effectively) called with no argument to initialize the RNG.

This can be seen with the following test program:

$ cat rand_test.rb
puts rand
puts rand
puts rand

$ ruby rand_test.rb
0.386885926082005
0.0444309071556157
0.147546420511617

$ ruby rand_test.rb
0.882099491922559
0.984145785659405
0.590537113434846

As you can see, each run of the program got a different set of random
numbers without ever needing to call srand.

To answer you last question, if you ever do need an integer
representing the current time, you can use +Time.now.to_f.to_i+.
Time.now gives you the current time as an object, Time#to_f converts
it to the number of milliseconds since the epoch and then Float#to_i
to truncate it down to an integer. You can also do +Time.now.to_i+ but
that’s grained to the second instead of milliseconds.

Jacob F.

On Nov 28, 2006, at 12:51 PM, [email protected] wrote:

Surely it must be possible to initialize rand with current date and
time.
Documents seem to indicate this is done with rand(0) or srand with
no value. I
have tried both methods and I get the same tired old sequence of
numbers. I
would write my own random number generator except I don’t know how
to get a
numeric value out of Time.

Can’t reproduce your problem. #srand with no argument seems to seed
the pseudo-random number generator with a different value on each
call. For example:

srand p Array.new(10) { rand(10) } srand(1) p Array.new(10) { rand(10) } srand p Array.new(10) { rand(10) } srand(1) p Array.new(10) { rand(10) } srand p Array.new(10) { rand(10) } [7, 8, 8, 1, 8, 3, 5, 6, 5, 2] [4, 9, 7, 9, 0, 1, 3, 9, 1, 2] [8, 4, 0, 0, 0, 7, 7, 4, 4, 4] [4, 9, 7, 9, 0, 1, 3, 9, 1, 2] [3, 9, 2, 9, 8, 0, 1, 0, 5, 9

Can you show us the code that didn’t work?

Regards, Morton

P.S. Concerning getting a numeric value out of Time:

Time.now.to_i

why not seed it from /dev/random/ in C/++ you’d do something like this:

unsigned int seed
FILE *devrandom = fopen("/dev/random", “r”);
fread(&seed,sizeof(seed),1,devrandom);

then pass the seed to rand, using the time itself is a bit dubious if
you want a strong set of random numbers, not a good idea for statistical
research / cryptography i fear.

On Nov 28, 2006, at 1011 , Christopher Coleman-Smith wrote:

why not seed it from /dev/random/

rand() is seeded by /dev/urandom by default.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On Nov 28, 2006, at 0951 , [email protected] wrote:

Surely it must be possible to initialize rand with current date and
time.
Documents seem to indicate this is done with rand(0) or srand with
no value. I
have tried both methods and I get the same tired old sequence of
numbers. I
would write my own random number generator except I don’t know how
to get a
numeric value out of Time.

On windows I think there is no way to seed from /dev/urandom, so you
get seeded by some default value. Instead the seed is composed of
the current time in seconds and microseconds and the pid.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com