By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,836 Members | 2,097 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,836 IT Pros & Developers. It's quick & easy.

srand in c or c++ doesn't really Generate Random Numbers ?

P: n/a
Hi All
I am using the srand function generate random numbers.Here is the
problem.

for example:
#include<iostream>
#include <time.h>

int main()
{
int i = 0,j = 0;

srand((int)time(0));

for(i=0; i<10; i++)
{
j=1+(int)(10.0*rand()/(RAND_MAX+1.0));
std::cout << j << '\t';
}
std::cout << std::endl;
return 0;
}
result:
5 8 8 8 10 2 10 8 9 9
2 9 7 4 10 3 2 10 8 7

The problem is that the two lines of the result are the same when the
compiler run over in one seconds.
How the function works?
how the computer make the rand numbers?
Does the function can generate really Random Numbers ?

Please help me out if you find some solution for the above problem.
Thanks in advancs !

Jul 3 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
On Jul 3, 12:45 pm, Chelong <hl.systemthin...@gmail.comwrote:
Hi All
I am using the srand function generate random numbers.Here is the
problem.

srand((int)time(0));
[code chopped]
for(i=0; i<10; i++)
{
j=1+(int)(10.0*rand()/(RAND_MAX+1.0));

The problem is that the two lines of the result are the same when the
compiler run over in one seconds.
time() returns time in seconds. If the seed for srand is same, the
same random number sequence will be returned. When your program runs
twice in 1 sec, the seed to srand is same and thus you get the same
sequence.
How the function works?
how the computer make the rand numbers?
Does the function can generate really Random Numbers ?
they are "pseudo" random numbers.

-Neelesh
Jul 3 '07 #2

P: n/a
Chelong <hl**************@gmail.comwrites:
Please help me out if you find some solution for the above problem.
Have a look at Boost's Random module. It's still a pseudo-random generator,
but there's no way around that without resorting to specialized hardware,
and it's a much better one than most compilers use.

<http://www.boost.org>

Also, from reading the above, I gather that Random is one of several Boost
modules that are included in TR1, so it's reasonably future-proof.

sherm--
Jul 3 '07 #3

P: n/a
On 7月3日, 下午4时35分, Sherm Pendley <spamt...@dot-app.orgwrote:
Chelong <hl.systemthin...@gmail.comwrites:
Please help me out if you find some solution for the above problem.

Have a look at Boost's Random module. It's still a pseudo-random generator,
but there's no way around that without resorting to specialized hardware,
and it's a much better one than most compilers use.

<http://www.boost.org>

Also, from reading the above, I gather that Random is one of several Boost
modules that are included in TR1, so it's reasonably future-proof.

sherm--
u all right!
thx!
they are "pseudo" random numbers.

Jul 3 '07 #4

P: n/a
Chelong wrote:
srand((int)time(0));
A quick solution is to use clock() instead of time().
Jul 3 '07 #5

P: n/a
On Jul 3, 4:03 pm, Juha Nieminen <nos...@thanks.invalidwrote:
Chelong wrote:
srand((int)time(0));

A quick solution is to use clock() instead of time().
Actually that's not recommended. clock() returns the number of clock
ticks since the _start of the program_ not since epoch or whatever.
Thus it will always give very similar values, because srand is usually
called at the start of the program. It will even give same values
almost always because usually the OS won't do a context switch (or any
other memory tricks) before the srand gets called and so a constant
number of instructions (and clock ticks) gets done before grabbing the
clock() value.

As Chelong says, boost::random is _the_ choice. It uses Mersenne
Twister algorithm which is way better and faster than the basic C/C++
rand().

You should take care when using rand(), because some Windows machines
let the rand() value to be just a two byte short, which sucks. It
doesn't matter usually though. Also, you shouldn't use the same seed
for more than one tenth or hundredth of the rand()'s granularity. So
for a four byte rand() you shouldn't generate more than ten million
random numbers with the same seed. This sounds pretty stupid, but many
number-crunching programs (such as those I have to write once in a
while) actually may use billions of random numbers. This does not
apply to the boost::random library's Mersenne Twister as you won't
need that many random numbers in your life as that algorithm can
generate before the randomness breaks.

Jul 9 '07 #6

P: n/a
"vulpes" <nt****@luukku.comwrote in message
news:11********************@n60g2000hse.googlegrou ps.com...
On Jul 3, 4:03 pm, Juha Nieminen <nos...@thanks.invalidwrote:
>Chelong wrote:
srand((int)time(0));

A quick solution is to use clock() instead of time().

Actually that's not recommended. clock() returns the number of clock
ticks since the _start of the program_ not since epoch or whatever.
Thus it will always give very similar values, because srand is usually
called at the start of the program. It will even give same values
almost always because usually the OS won't do a context switch (or any
other memory tricks) before the srand gets called and so a constant
number of instructions (and clock ticks) gets done before grabbing the
clock() value.

As Chelong says, boost::random is _the_ choice. It uses Mersenne
Twister algorithm which is way better and faster than the basic C/C++
rand().

You should take care when using rand(), because some Windows machines
let the rand() value to be just a two byte short, which sucks. It
doesn't matter usually though. Also, you shouldn't use the same seed
for more than one tenth or hundredth of the rand()'s granularity. So
for a four byte rand() you shouldn't generate more than ten million
random numbers with the same seed. This sounds pretty stupid, but many
number-crunching programs (such as those I have to write once in a
while) actually may use billions of random numbers. This does not
apply to the boost::random library's Mersenne Twister as you won't
need that many random numbers in your life as that algorithm can
generate before the randomness breaks.
It seems that time() + clock() would do the trick, no?
Jul 9 '07 #7

P: n/a
On 2007-07-09 16:28:11 -0400, vulpes <nt****@luukku.comsaid:
>
As Chelong says, boost::random is _the_ choice. It uses Mersenne
Twister algorithm which is way better and faster than the basic C/C++
rand().
There is no boost::random class or template. There are a handful of
random number generators in Boost, and they've been incorporated into
TR1. mersenne_twister is one of them. Whether it's "way better" depends
on your application. It's certainly much bigger than the typical C
implementation of rand, both in the size of its code and in the amount
of data that it stores.
>
You should take care when using rand(), because some Windows machines
let the rand() value to be just a two byte short, which sucks. It
doesn't matter usually though.
Well, if it usually doesn't matter, then it doesn't categorically "suck."
Also, you shouldn't use the same seed
for more than one tenth or hundredth of the rand()'s granularity. So
for a four byte rand() you shouldn't generate more than ten million
random numbers with the same seed. This sounds pretty stupid, but many
number-crunching programs (such as those I have to write once in a
while) actually may use billions of random numbers. This does not
apply to the boost::random library's Mersenne Twister as you won't
need that many random numbers in your life as that algorithm can
generate before the randomness breaks.
Okay, so you shouldn't do it, except when it's okay to do it.

Bottom line: choosing a random number generator requires far more data
than is present here, and sweeping generalities aren't helpful.

--
-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jul 9 '07 #8

P: n/a
On Jul 9, 10:28 pm, vulpes <ntv...@luukku.comwrote:
On Jul 3, 4:03 pm, Juha Nieminen <nos...@thanks.invalidwrote:
Chelong wrote:
srand((int)time(0));
A quick solution is to use clock() instead of time().
Actually that's not recommended. clock() returns the number of clock
ticks since the _start of the program_ not since epoch or whatever.
Thus it will always give very similar values, because srand is usually
called at the start of the program. It will even give same values
almost always because usually the OS won't do a context switch (or any
other memory tricks) before the srand gets called and so a constant
number of instructions (and clock ticks) gets done before grabbing the
clock() value.
It's worse. The start time is only "related only to the program
invocation". At least under Solaris, the first call to clock()
always returns 0.

There are a number of system dependant solutions; under Unix,
for example, you can open "/dev/random", and read a couple of
bytes, or use gettimeofday to get the time in microseconds (but
the actual granularity won't be that fine). Hashing in a number
of various values, like the process id and the machine map
address, can be used as well.
As Chelong says, boost::random is _the_ choice. It uses Mersenne
Twister algorithm which is way better and faster than the basic C/C++
rand().
Boost random is a component, not a single class. You choose the
algorithm, and all of the algorithms require a seed, so using
Boost doesn't affect the problem the original poster had. I'm
curious about "faster" as well. A linear congruent generator is
just a multiplication and a modulo; the Mersenne twister seems
to do a lot more operations than just those. So if your machine
has good 64 bit hardware multiply and divide, the minimum
standard generator should be a lot faster. (This will obviously
depend on the machine, of course.)

Independantly of the speed, of course, rand() is often poorly
implemented, and you're better off using one of the Boost
algorithms, all of which have specified behavior, so you can
know what you are getting.
You should take care when using rand(), because some Windows machines
let the rand() value to be just a two byte short, which sucks.
For historical reasons, any number of machines declare RAND_MAX
to be 32767. For historical reasons, a lot of machines have a
very poor rand().
It doesn't matter usually though. Also, you shouldn't use the
same seed for more than one tenth or hundredth of the rand()'s
granularity.
What do you mean by granularity? Obviously, you don't want to
use more than a small part of the generator's cycle, but it's
fairly simple to combine generators if you need a longer cycle.
Or use the lagged fibonacci from boost. (In practice, it
depends on your needs. For most interactive game playing, I
would guess that the period of any of the Boost algorithms would
be sufficient.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34

Jul 10 '07 #9

P: n/a
On Jul 9, 10:30 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:
"vulpes" <ntv...@luukku.comwrote in message
news:11********************@n60g2000hse.googlegrou ps.com...
[...]
It seems that time() + clock() would do the trick, no?
Under Solaris, the first call to clock() always returns 0. If
you're running on the same machine, getpid() (Unix) or
GetCurrentProcessId() (Windows), should provide enough
additional differentiation; if you're worried about the same
seed on different processors, you can throw in the MAP address
or the IP address as well. Both systems also provide the time
with additional precision (gettimeofday(), under Unix, or
GetSystemTime() under Windows).

Also, I'd use some sort of hash code for combining them, and not
just adding.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34

Jul 10 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.