SRAND Number Generation Help
I am spending too much time wrapping my head around srand() without success. I need some help around this simple little bit. Here is my timely dilemma...
These are my includes:
#include <cstdlib> //For srand() and rand().
#include <ctime> //For time().
My initializations:
int gameTime = 1200;
double randomTime;
srand(time(0));
randomTime = (rand() % 1000) + 1;
My (supposedly working) generator:
gameTime = randomTime - gameTime;
In the body:
cout << "Do not forget, your current time is: " << gameTime << " minutes.\n";
Dilemma:
The output keeps going back and forth between these two numbers:
Do not forget, your current time is: -660 minutes.
Do not forget, your current time is: 1200 minutes.
And back to 1200 again.
It is supposed to be going from 1200 down to 0, randomly subtracting numbers.
Thank you for any help with this bit. I have been meaning to ask this for months, just been busy.
Re: SRAND Number Generation Help
In despite of the fact that your code makes absolutely no sense, what it is lacking is a good way to "seed the randomizer" before it's used. The way it should be done is something like this:
Code:
UINT uSeed = (UINT)time(NULL);
srand(uSeed);
for(int i = 0; i < (uSeed & 0xfff); i++)
rand();
The code above should be called only once when your app starts. This way it will ensure a totally (pseudo-) random number when you call rand().
As for the reasons why you were getting such a non-random result, you must understand that rand() is not technically producing a random number. It simply does the following mathematical function to produce an non-repeating sequence of numbers:
Code:
return ((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff;
The actual "randomness" should be added in the call to srand(), what the code snippet on top attempts to simulate.
Re: SRAND Number Generation Help
The code does not make sense because I just gave the main points of my issue. No reason to send over the whole code, is there?
I will see if I can figure out this seeding process. Thanks for the tip.
Re: SRAND Number Generation Help
From the little fragment I see, you are only calling rand() once anyway. What do you expect?
Just think for a second about the math. Say your (cough) 'RandomTime' comes out to be 500 the single time you do anything to it.
Pass 1: 500 - 1200 = -700
Pass 2: 500 - (-700) = 1200
Pass 3: 500 - 1200 = -700.
See a pattern there?
Re: SRAND Number Generation Help
But when the other commands in main are using the same formula, gameTime should be taking the value from when it last was, so the countdown should keep going down.
I do not know if you people are helping and being funny or criticizing. If you want the whole code, say so. Do not act like this please.
The way I have the code set up, it is supposed to keep looping using the new gameTime each time in each pass and hit 0 eventually.
Re: SRAND Number Generation Help
Quote:
Originally Posted by TruthSpeaker
If you want the whole code, say so.
Post the smallest and simplest compilable program that demonstrates the problem (i.e., only post your whole code if it does not contain anything irrelevant to this problem.
Re: SRAND Number Generation Help
You need to show enough code to reproduce the problem.
Perhaps in this statemen
gameTime = randomTime - gameTime;
you have randomTime and gameTime backwards.
If gameTime starts at 1200 and randomTime is less than 1,000 you'll end up with a negative number at your first subtraction. If that isn't it, show more code.
Re: SRAND Number Generation Help
laser, GCD, thank you (no criticism, love it).
I still need to look into DC's example and then if that fails, look into yours and post only the part you need to see.
Thank you.
Re: SRAND Number Generation Help
GCDEF, genius! So simple! I swear I have tried that dozens of times before, but may have done so with different variants of generators. Probably did not try with this current method I am using. WOW. See, it was that simple. Thank you.
Re: SRAND Number Generation Help
Quote:
Originally Posted by
TruthSpeaker
Quote:
Originally Posted by GCDEF
Perhaps in this statemen
gameTime = randomTime - gameTime;
you have randomTime and gameTime backwards.
If gameTime starts at 1200 and randomTime is less than 1,000 you'll end up with a negative number at your first subtraction.
GCDEF, genius! So simple! I swear I have tried that dozens of times before, but may have done so with different variants of generators...
:) TruthSpeaker, your common sense is not with you, is it?
Even if you catch that your random number is in the range from 1 to 1000 and you're subtracting 1200 from it, it will still not change the point that you're not sufficiently seeding your randomizer (that was the subject of your question by the way.)
Re: SRAND Number Generation Help
Quote:
Originally Posted by dc_2000
it will still not change the point that you're not sufficiently seeding your randomizer (that was the subject of your question by the way.)
I do not think that we can definitely draw that conclusion from TruthSpeaker's original post due to the lack of sufficient context. If the relevant code snippet was from a function that was called many times then that would apply, but it might also be the case that that control passed through that code snippet no more than once.
Your suggested method of seeding the PRNG is interesting though: the actual call to srand() is effectively the same as what TruthSpeaker used, but the difference is that the first few numbers in the sequence are discarded, with the exact number of numbers depending on the seed value. I suspect that that is unnecessary, since if one is able to determine the seed and knows the algorithm, one can still obtain the seed. This article on using rand() proposes a hash of the bytes returned by time(0) as a seed instead, or perhaps just discarding the first number in the sequence.
Quote:
Originally Posted by dc_2000
It simply does the following mathematical function to produce an non-repeating sequence of numbers:
The implementation of rand() is implementation defined and the sequence is not guaranteed to be non-repeating.
Re: SRAND Number Generation Help
Quote:
The implementation of rand() is implementation defined and the sequence is not guaranteed to be non-repeating.
Last time I heard, every pseudo random generator is guaranteed to repeat at one point or another. It just depends on how much time it'll take.
rand() usually repeats every 2^32 or 2^64, depending on implementation. What's more problematic, is that if the rand() function uses a linear congruential generator (which it usually does), then it always repeats the same sequence. srand would only define where on that sequence you start.
Re: SRAND Number Generation Help
Quote:
Originally Posted by
laserlight
The implementation of rand() is implementation defined and the sequence is not guaranteed to be non-repeating.
OK, you're right. What I should've said is that the rand() is a simple mathematical function with a long periodicity.
Quote:
Originally Posted by laserlight
Your suggested method of seeding the PRNG is interesting though: the actual call to srand() is effectively the same as what TruthSpeaker used
Again, the reason I suggested that method of seeding is because the OP stated that the output repeats itself, which it may very well do if srand() and rand() are used like he did. The reason? If you look at his code, that effectively becomes this:
Code:
time_t t = time(0);
int holdrand = t;
randomTime = ((((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff) % 1000) + 1;
In which case time() returns the current time in seconds elapsed since midnight of January 1, 1970, then rand() mutiplies it by 214,013 and right-shifts it 16 bits, which is the same as dividing it by 65,536. It then lops off 17 high bits and returns the result. So in a sense it is as if you (roughly) mutiply the time value by 3.3 and remove all the high bits off of the result. As you can imagine the periodicity of that function will be very low. It will also result in almost equal, or repeating results if the OP tried his code one time after another, not waiting for more than a few seconds (since again time() function is involved). What I suggested is a more complex way to seed the randomizer that will eliminate such dependency on "direct" time() call when used in his code.
Re: SRAND Number Generation Help
dc, if your rude comments are going to continue, please do not post. I do not know if you trying to be funny but I see no humor. I came here looking for helpful comments, not criticism. go elsewhere for that please.
Re: SRAND Number Generation Help
Quote:
Originally Posted by
TruthSpeaker
I came here looking for helpful comments, not criticism.
Criticism is usually the most helpful kind of comment, so long as it's well thought out.
dc's comments are probably more theoretical than you really need, but you would do well to try to understand what he's saying.
The most important aspect of it? Call srand() only once per program run. Call rand() many times.