# First random number is not random

This topic is 4619 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have the following very simple piece of code:
#include <iostream>
#include <ctime>

namespace
{
bool g_seeded = false;
}

int RandomInt(const int min, const int max)
{
if(!g_seeded)
{
srand(time(0));
g_seeded = true;
}

return min + int((max - min + 1) * rand() / (RAND_MAX + 1.0));
}

int main()
{
std::cout << RandomInt(0, 7) << "\n";

return 0;
}


It's been only printing 7 for me, and I don't see why. If I call RandomInt() more than once, then the values are random, but for the first time it's always the same. Does anyone know why that would be? [sad]

##### Share on other sites
Quote:
 Original post by HyloLooks like the first time through you dont seed the random number generator..Andrew

Actually, he's doing that part fine.

The problem is in how you implemented RandomInt()... Try changing it to:

return min + rand()%(max-min+1);

...

The reason your version didn't work is a little hard to explain. Let me just tell you this... rand() returns a number from 0 to 32,767 if I remember correctly. Now the thing is, every second, the 1st number returned by rand increases by 1 (this is because you are seeding based on time(NULL) which is in *seconds*).

So, run your program the 1st time, maybe the 1st number returned is 9,124. Then wait 5 seconds, run it again, now it returns 9,129... And so on... Because of the way you set up your math though, 9,124 and 9,129 map to the same number. That's why it's better to use the modulus (%) operator.

Hope that makes sense :)

roos

##### Share on other sites
Quote:
 Original post by HyloLooks like the first time through you reseed the generator with the same numerAndrew

Nope. It's a different value everytime provided the next time you run the program it has been over about a second later.

EDIT:
Quote:
Original post by roos
Quote:
 Original post by HyloLooks like the first time through you dont seed the random number generator..Andrew

Actually, he's doing that part fine.

The problem is in how you implemented RandomInt()... Try changing it to:

return min + rand()%(max-min+1);

...

The reason your version didn't work is a little hard to explain. Let me just tell you this... rand() returns a number from 0 to 32,767 if I remember correctly. Now the thing is, every second, the 1st number returned by rand increases by 1 (this is because you are seeding based on time(NULL) which is in *seconds*).

So, run your program the 1st time, maybe the 1st number returned is 9,124. Then wait 5 seconds, run it again, now it returns 9,129... And so on... Because of the way you set up your math though, 9,124 and 9,129 map to the same number. That's why it's better to use the modulus (%) operator.

Hope that makes sense :)

roos

Ah, that does indeed make sense [smile]. CANDY FOR YOU. Come to think of it, the program started printing 0 10 minutes later instead of 7.

Now, does: min + rand()%(max-min+1) have good "randomness"? I've heard certain formulas for calculating random numbers have problems because of not taking into account "low bits" or something or other. Is there a "best" way to calculate random numbers like this?

##### Share on other sites
double Random() // returns [0,1) {  static bool seeded(false);   if(!seeded)   {    srand(time(0));    seeded = true;   }    return static_cast<double>(rand())/static_cast<double>(RAND_MAX+1); }template <typename T> T Random(const T &min, const T &max) // returns [min,max) {  return min+static_cast<T>(static_cast<double>(max-min)*Random()); }

##### Share on other sites
Quote:
 Original post by smart_idiot *** Source Snippet Removed ***

Ooh! Templated! Very nice. I think I will use this. [smile]

##### Share on other sites
Well... rand() isn't bad, but it depends on what you are doing. Personally, I've never really run into a situation where rand() didn't do the job.

As far as other RNG algorithms go, I haven't tried any but I have heard of one called Mersenne Twister. It's supposedly pretty good and fast to compute..

roos

##### Share on other sites
++vote for Mersenne Twister.

##### Share on other sites
Quote:
 Original post by roosWell... rand() isn't bad, but it depends on what you are doing. Personally, I've never really run into a situation where rand() didn't do the job.As far as other RNG algorithms go, I haven't tried any but I have heard of one called Mersenne Twister. It's supposedly pretty good and fast to compute..roos

Quote:
 Original post by smart_idiot++vote for Mersenne Twister.

This "Mersenne Twister" sounds very good; I just wikipediaed it. I'll go see what it does, thanks again roos/smart_idiot.

##### Share on other sites
Quote:
 Original post by roosActually, he's doing that part fine.The problem is in how you implemented RandomInt()... Try changing it to:return min + rand()%(max-min+1);...The reason your version didn't work is a little hard to explain. Let me just tell you this... rand() returns a number from 0 to 32,767 if I remember correctly. Now the thing is, every second, the 1st number returned by rand increases by 1 (this is because you are seeding based on time(NULL) which is in *seconds*).So, run your program the 1st time, maybe the 1st number returned is 9,124. Then wait 5 seconds, run it again, now it returns 9,129... And so on... Because of the way you set up your math though, 9,124 and 9,129 map to the same number. That's why it's better to use the modulus (%) operator.Hope that makes sense :)roos

Don't use the modulus operator. It is biased towards the low order bits, which are often less random than the high order bits. As you explain, consecutive calls to time(0) have most of their variation in those low order bits, so for that first call [and only for that first call], a modulus might well be a better move. But you only seed once, so in the long run his original implementation was not only fine, but preferable on many systems.

If you are running your program so quickly that you see such problems, just throw away your first value.
if(!g_seeded){    srand(time(0));    rand();    g_seeded = true;}

CM