12

I have a C++ application which calls rand() in various places. Do I need to initialize srand() regularly to ensure that rand() is reasonably random, or is it enough to call it once when the app starts?

laurent
  • 88,262
  • 77
  • 290
  • 428
  • 2
    `srand` does not make `rand` "more" random. It doesn't ensure "reasonable randomness" in any way. It just makes the sequence of random numbers start from the specified point. – jalf Aug 05 '11 at 09:58
  • @jalf I'm surprised that in over 8 years since this comment was made it has not been challenged. The claim "It just makes the sequence of random numbers start from the specified point" seems to be contradicted by cplusplus.com: "For every different seed value used in a call to srand, the pseudo-random number generator can be expected to generate a different succession of results in the subsequent calls to rand." – Theo d'Or Jan 16 '20 at 13:59
  • @Theod'Or, both jalf comment and your quote from cplusplus say pretty the same thing. What's the difference? – laurent Jan 16 '20 at 16:39
  • @laurent The difference is in starting from a specified point versus generating a different succession of results. The former suggests that the range of numbers generated will always be the same, no matter what the seed, the latter suggests different numbers for different seeds. I guess your reading of the latter is that it may also be interpreted to possibly mean just a different starting point in an otherwise unchanging sequence. But in that case the cplusplus statement is only true until the end of the generation period. – Theo d'Or Jan 16 '20 at 19:10
  • Actually, [Wikipedia](https://en.wikipedia.org/wiki/Linear_congruential_generator) claims `rand()` is a _linear congruential generator_, and as their illustration shows, a new seed, if it does not match a number the generator would produce with the previous seed, will result in a different sequence of numbers. If the seed matches though, only the starting point changes. – Theo d'Or Jan 19 '20 at 14:26
  • Except that I've just done a test and do not get a different starting point with a seed matching a previous output, but a different sequence. I suspect the Wikipedia article is out of date and `rand()` is no longer a simple _linear congruential generator_. – Theo d'Or Jan 19 '20 at 15:49

4 Answers4

18

If you have only a single thread, seed once. If you reseed often, you might actually break some of the statistical properties of the random numbers. If you have multiple threads, don't use rand at all, but rather something threadsafe like drand48_r, which lets you maintain a per-thread state (so you can seed once per thread).

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    Boost::random is more portable than drand48_r, or use the C++0x random (which is a Boost derivative) – MSalters Aug 05 '11 at 12:25
  • 2
    @MSalters: Of course, I'd go for the new `` features any day. They're just a little more involved to set up, so I thought I answer in the spirit of the question -- but indeed, do use `` if you can! – Kerrek SB Aug 05 '11 at 12:35
  • Thanks for this very complete answer. – laurent Aug 06 '11 at 14:17
  • 1
    "If you reseed often, you might actually break some of the statistical properties of the random numbers." Some evidence to back up this claim would be very welcome. – Theo d'Or Jan 16 '20 at 14:00
  • @Theod'Or: By omission: RNGs don't generally make guarantees about their initial value relative to the seed, but only to the statistics of a rollout starting at (any) one fixed seed. – Kerrek SB Jan 25 '20 at 22:03
4

Only once, at the start of your application.

Dr McKay
  • 2,548
  • 2
  • 21
  • 26
4

No just calling once is fine. Use the seed value to make the random sequence the same on each execution. This could be useful in making (for example) a game's behaviour deterministic when you replay it for debugging.

Paul Carroll
  • 1,523
  • 13
  • 15
3

call it once when the app starts

cprogrammer
  • 5,503
  • 3
  • 36
  • 56