Jump to content
  • Advertisement
Sign in to follow this  
load_bitmap_file

First random number is not random

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Hylo
Looks 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 this post


Link to post
Share on other sites
Quote:
Original post by Hylo
Looks like the first time through you reseed the generator with the same numer


Andrew


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 Hylo
Looks 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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by roos
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


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 this post


Link to post
Share on other sites
Quote:
Original post by roos
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

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!