srand() problem

Started by
9 comments, last by DevFred 15 years, 10 months ago
Many sources encourage the use of srand(time(0)) or srand(time(NULL)). But I noticed something weird:
#include <iostream>
#include <time.h>
using namespace std;

void main()
{
	srand(time(NULL));
	cout<<rand()<<endl;
}

. If I run this program repeatedly, I noticed that the output values are very similar, and they are steadily increasing- so no randomness! Eg first I get 25196, then 25203, 25435 etc. Why is this?
Advertisement
Quote:Original post by asdqwe
Many sources encourage the use of
srand(time(0)) or srand(time(NULL)).
But I noticed something weird:
*** Source Snippet Removed ***. If I run this program repeatedly, I noticed that the output values are very similar, and they are steadily increasing- so no randomness! Eg first I get 25196, then 25203, 25435 etc.
Why is this?
time() will return the same value if you call it within a second (Since it returns values in seconds). That'd cause it to show the same values if you run it quickly.

As for steadily increasing values, that just sounds like coincidence to me. The first few values might be like that I suppose, but it should give roughly random numbers after that, so long as you only call srand() once at startup (Which you should be doing).
To Evil Steve: Coincidence? I've just run it 40 times- the numbers are steadily increasing- 28210, 28221, 28240, 28254 etc... And I run the exact code I've provided!
Quote:As for steadily increasing values, that just sounds like coincidence to me. The first few values might be like that I suppose, but it should give roughly random numbers after that, so long as you only call srand() once at startup (Which you should be doing).


I have to say I believed this too. But then I just tried it out:

20192202712031020329203592045720502205742060020626206332063620640


These are the numbers I got on a quick run through. After the first call, however, it's more random. VS.NET 2005. It looks like the first value returned from the random function after seeding is more closely related to the seed than each additional call - as in, since the time is increasing, so are these numbers. I don't know what the internal algorithm is used by the VS.NET C++ rand() function, however, and after the first call to rand the numbers were properly "randomized" so not really a huge issue - just interesting.
You could always seed with clock() instead:
#include <iostream>#include <time.h>using namespace std;void main(){	srand(clock());	cout<<rand()<<endl;}
That should give you a more "random" first value. But as CaspianB said, it really doesn't matter that much - it's very unlikely you'll call rand() once and only once.
Or try rand_s()
The rand() function is often implemented with a linear congruence PRNG, i.e. the first value will be (time(null)*A+B)%C, with A,B and C being some constants.
If you are not satisfied with the first random number, just use the second:

#include <iostream>#include <ctime>using namespace std;int main(){	srand(time(0));	rand(); // discard first random number	cout << rand() << endl;}
Thanks!
You may want to use a more sophisticated random generator instead, such as a Mersenne twister. Depending on how important this is to you, of course. :)
Create-ivity - a game development blog Mouseover for more information.

This topic is closed to new replies.

Advertisement