I made a program that produces a different random number 10 times.
Here is the code:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
srand(time(0));
for (int i = 0; i <10; i++) {
std::cout << rand() % 100 << std::endl;
}
return 0;
}
It runs fine. However, I do not understand why. I did some research and based on what I understand:
rand()
is always seeded to 1, which therefore produces the same number- In order to generate different results, I have to seed it with something different(like the time) by doing this :
srand(time(0))
My concern is: if I set the seed once outside the loop, shouldn't rand()
produce the same number? Because based on what I know, rand()
gives pseudo-random numbers, which are "fake", and I understood that it follows a certain predictable algorithm, which means that in every iteration of the loop it uses the same seed set outside the loop which is supposed to give me the same numbers. Why would I get different numbers?
I made a program that produces a different random number 10 times.
Here is the code:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main() {
srand(time(0));
for (int i = 0; i <10; i++) {
std::cout << rand() % 100 << std::endl;
}
return 0;
}
It runs fine. However, I do not understand why. I did some research and based on what I understand:
rand()
is always seeded to 1, which therefore produces the same number- In order to generate different results, I have to seed it with something different(like the time) by doing this :
srand(time(0))
My concern is: if I set the seed once outside the loop, shouldn't rand()
produce the same number? Because based on what I know, rand()
gives pseudo-random numbers, which are "fake", and I understood that it follows a certain predictable algorithm, which means that in every iteration of the loop it uses the same seed set outside the loop which is supposed to give me the same numbers. Why would I get different numbers?
3 Answers
Reset to default 6srand()
is seeding the random generator.
This means that for every seed there will be a sequence of pseudo random values that the generator can produce (not a single value).
Every call to rand()
will return the next value in the sequence.
The documentation explicitly mentions that:
Generally speaking, the pseudo-random number generator should only be seeded once, before any calls to rand(), at the start of the program. It should not be repeatedly seeded, or reseeded every time you wish to generate a new batch of pseudo-random numbers.
Therefore calling srand()
once is not only OK in your case, it is actually the recommended way.
A side note:
In C++ is it recommended to use <random>
instead of the lagacy rand()
.
See more info here: How to generate a random number in C++?.
A pseudo random number generator such as rand has indeed a behavior defined by its seed. However, this behavior is not just a single output, but a sequence of outputs.
Internally, a PRNG is a numeric sequence, and the seed influences how this sequence starts (and, possibly, how it evolves). From there, the machinery transforms each successive result in a deterministic but seemingly random way.
You can try this yourself: in your program, give a fixed arbitrary number to srand and you'll see that each time you run your program, you'll get the same output!
A really bad implementation of rand
(but still meeting the requirements of the standard) could look something like this:
#include <iostream>
#include <cstdlib>
#include <ctime>
unsigned randomState = 1;
const int MY_RAND_MAX = 0x7FFFFFF;
void mysrand(unsigned seed)
{
randomState = seed;
}
int myrand()
{
randomState += 3150171407;
return (int)(randomState & MY_RAND_MAX);
}
int main() {
mysrand(time(0));
for (int i = 0; i <10; i++) {
std::cout << myrand() % 100 << std::endl;
}
return 0;
}
srand
initialises the random number generators internal state using the specified value. Each call to rand
then applies some algorithm to the internal state, modifying the state and returning a psuedo-random number. The next call to rand
will start from the now modified state and produce a different number.
Hopefully your standard library's implementation of rand
is higher quality than mine but it'll basically follow the same pattern with just a more appropriate algorithm used inside rand
.
There's no guarantee that the standard library does have a good quality implementation see Why is the use of rand() considered bad. Using rand() % 100
will make rand
's output even worse, lower numbers will be more likely to be produced than higher ones due to biases introduced by using modulus. Both issues can be fixed by using the c++11 standard library random number generation.
rand()
) will still be different. In any case it is recommended to use<random>
instead ofrand()
in C++. See here: stackoverflow/questions/13445688/…. – wohlstad Commented Feb 16 at 10:43time(0)
gives you a different starting point each time you run the program, so different random numbers. – BoP Commented Feb 16 at 12:11