This comment, which states:
srand(time(0));
I would put this line as the first line in main() instead if calling it multiple times (which will actually lead to less random numbers).
...and I've bolded the line which I'm having an issue with... repeats common advice to call srand
once in a program. Questions like srand() — why call only once? re-iterate that because time(0)
returns the current time in seconds, that multiple calls to srand
within the same second will produce the same seed. A common workaround is to use milliseconds or nanoseconds instead.
However, I don't understand why this means that srand
should or can only be called once, or how it leads to less random numbers.
Generally speaking, the pseudo-random number generator should only be seeded once, before any calls to rand(), and 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.
phoxis's answer to srand() — why call only once?:
Initializing once the initial state with the seed value will generate enough random numbers as you do not set the internal state with srand, thus making the numbers more probable to be random.
Perhaps they're simply using imprecise language, none of the explanations seem to explain why calling srand
multiple times is bad (aside from producing the same sequence of random numbers) or how it affects the "randomness" of the numbers. Can somebody clear this up for me?
A pseudo random generator is an engine which produce numbers that look almost random. However, they are completely deterministic. In other words, given a seed
x0
, they are produced by repeated application of some injective function onx0
, call itf(x0)
, so thatf^m(x0)
is quite different fromf^{m-1}(x0)
orf^{m+1}(x0)
, where the notationf^m
denotes the function compositionm
times. In other words,f(x)
has huge jumps, almost uncorrelated with the previous ones.If you use
sradnd(time)
multiple times in a second, you may get the same seed, as the clock is not as fast as you may imagine. So the resulting sequence of random numbers will be the same. And this may be a (huge) problem, especially in cryptography applications (anyway, in the latter case, people buy good number generators based on real-time physical processes such as temperature difference in atmospheric data etc, or, recently, on measuring quantum bits, e.g. superposition of polarized photons, the latter being truly random, as long as quantum mechanics is correct.)There are also other serious issues with
rand
. One of it is that the distribution is biased. See e.g. http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx for some discussion, although I remember I've seen something similar on SO, although cannot find it now.If you plan to use it in crypto applications, just don't do it. Use
<random>
and a serious random engine like Mersene's twisterstd::mt19937
combined withstd::random_device
If you seed your random number generator twice using
srand
, and get different seeds, then you will get two sequences that will be quite different. This may be satisfactory for you. However, each sequence per se will not be a good random distribution due to the issues I mentioned above. On the other hand, if you seed your rng too many times, you will get the same seed, and THIS IS BAD, as you'll generate the same numbers over and over again.PS: seen in the comments that pseudo-numbers depend on a seed, and this is bad. This is the definition of pseudo-numbers, and it is not a bad thing as it allows you to repeat numerical experiments with the same sequence. The idea is that each different seed should produce a sequence of (almost) random numbers, different from a previous sequence (technically, you shouldn't be able to distinguish them from a perfect random sequence).