By Lipika Deka


2011-09-08 06:13:49 8 Comments

This question is about a comment in this question Recommended way to initialize srand? The first comment says that srand() should be called only ONCE in an application. Why is it so?

7 comments

@Steve Summit 2016-10-25 21:29:07

Short answer: calling srand() is not like "rolling the dice" for the random number generator. Nor is it like shuffling a deck of cards. If anything, it's more like just cutting a deck of cards.

Think of it like this. rand() deals from a big deck of cards, and every time you call it, all it does is pick the next card off the top of the deck, give you the value, and return that card to the bottom of the deck. (Yes, that means the "random" sequence will repeat after a while. It's a very big deck, though: typically 4,294,967,296 cards.)

Furthermore, every time your program runs, a brand-new pack of cards is bought from the game shop, and every brand-new pack of cards always has the same sequence. So unless you do something special, every time your program runs, it will get exactly the same "random" numbers back from rand().

Now, you might say, "Okay, so how do I shuffle the deck?" And the answer -- at least as far as rand and srand are concerned -- is that there is no way of shuffling the deck.

So what does srand do? Based on the analogy I've been building here, calling srand(n) is basically like saying, "cut the deck n cards from the top". But wait, one more thing: it's actually start with another brand-new deck and cut it n cards from the top.

So if you call srand(n), rand(), srand(n), rand(), ..., with the same n every time, you won't just get a not-very-random sequence, you'll actually get the same number back from rand() every time. (Probably not the same number you handed to srand, but the same number back from rand over and over.)

So the best you can do is to cut the deck once, that is, call srand() once, at the beginning of your program, with an n that's reasonably random, so that you'll start at a different random place in the big deck each time your program runs. With rand(), that really is the best you can do.

[P.S. Yes, I know, in real life, when you buy a brand-new deck of cards it's typically in order, not in random order. For the analogy here to work, I'm imagining that each deck you buy from the game shop is in a seemingly random order, but the exact same seemingly-random order as every other deck of cards you buy from that same shop. Sort of like the identically shuffled decks of cards they use in bridge tournaments.]

@DrunkenMaster 2019-07-02 06:38:30

Superb explanation Steve.

@achoora 2016-01-11 11:46:59

A simpler solution for using srand() for generating different seeds for application instances run at the same second is as seen.

srand(time(NULL)-getpid());

This method makes your seed very close to random as there is no way to guess at what time your thread started and the pid will be different also.

@Kornelije Petak 2011-09-08 06:20:07

That depends on what you are trying to achieve.

Randomization is performed as a function that has a starting value, namely the seed.

So, for the same seed, you will always get the same sequence of values.

If you try to set the seed every time you need a random value, and the seed is the same number, you will always get the same "random" value.

Seed is usually taken from the current time, which are the seconds, as in time(NULL), so if you always set the seed before taking the random number, you will get the same number as long as you call the srand/rand combo multiple times in the same second.

To avoid this problem, srand is set only once per application, because it is doubtful that two of the application instances will be initialized in the same second, so each instance will then have a different sequence of random numbers.

However, there is a slight possibility that you will run your app (especially if it's a short one, or a command line tool or something like that) many times in a second, then you will have to resort to some other way of choosing a seed (unless the same sequence in different application instances is ok by you). But like I said, that depends on your application context of usage.

Also, you may want to try to increase the precision to microseconds (minimizing the chance of the same seed), requires (sys/time.h):

struct timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);

@Shahbaz 2013-04-07 10:23:09

Side note: gettimeofday is obsolete in POSIX 2008. Instead, it introduces clock_gettime which may require linking with -lrt. It may not yet be available on many platforms, though. In Linux this is alright. On Mac I think it's not yet available. In Windows it will probably never be available.

@Jiminion 2017-04-26 13:12:10

t1.tv_usec is a long int, and srand takes as input an unsigned int. (And I just ran into a problem where it makes a difference.)

@imoc 2017-12-02 06:14:49

1\Seems every time rand() runs, it will set a new seed for the next rand().

2\If srand() runs multiple times, the problem is if the two running happen in one second(the time(NULL) does not change), the next rand() will be the same as the rand() right after the previous srand().

@King Thrushbeard 2017-12-02 06:25:34

The main point is that initializing with srand() several times with the same seed will result in identical values returned by rand().

@phoxis 2011-09-08 10:15:04

Random numbers are actually pseudo random. A seed is set first, from which each call of rand gets a random number, and modifies the internal state and this new state is used in the next rand call to get another number. Because a certain formula is used to generate these "random numbers" therefore setting a certain value of seed after every call to rand will return the same number from the call. For example srand (1234); rand (); will return the same value. 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.

Generally we use the time (NULL) returned seconds value when initializing the seed value. Say the srand (time (NULL)); is in a loop. Then loop can iterate more than once in one second, therefore the number of times the loop iterates inside the loop in a second rand call in the loop will return the same "random number", which is not desired. Initializing it once at program start will set the seed once, and each time rand is called, a new number is generated and the internal state is modified, so the next call rand returns a number which is random enough.

For example this code from http://linux.die.net/man/3/rand:

static unsigned long next = 1;
/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned seed) {
    next = seed;
}

The internal state next is declared as global. Each myrand call will modify the internal state and update it, and return a random number. Every call of myrand will have a different next value therefore the the method will return the different numbers every call.

Look at the mysrand implementation; it simply sets the seed value you pass to next. Therefore if you set the next value the same everytime before calling rand it will return the same random value, because of the identical formula applied on it, which is not desirable, as the function is made to be random.

But depending on your needs you can set the seed to some certain value to generate the same "random sequence" each run, say for some benchmark or others.

@Jiminion 2017-04-26 13:15:56

Don't you mean (unsigned long seed) for the parameter of mysrand() ?

@phoxis 2017-05-08 10:22:22

@Jiminion This is a code snippet from man srand . The range is from 0 to 32767 (assuming RAND_MAX), which is way less than the long range. The state variable next is made long as the internal multiplication and addition will exceed the range of an unsigned int. After that the result is scaled or modified within the above specified range. Though you can make the seed long.

@Jonathan Leffler 2017-09-07 05:15:36

Note that the C standard includes the snippet of code shown too.

@Foo Bah 2011-09-08 06:20:46

srand seeds the pseudorandom number generator. If you call it more than once, you will reseed the RNG. And if you call it with the same argument, it will restart the same sequence.

To prove it, if you do something simple like:

#include <cstdlib>
#include <cstdio>
int main() {
for(int i = 0; i != 100; ++i) {
        srand(0);
        printf("%d\n", rand());
    }
}

you will see the same number printed 100 times.

@Spikatrix 2015-10-17 05:48:23

The question is about C, not C++.

@sharptooth 2011-09-08 06:15:26

The reason is that srand() sets the initial state of the random generator, and all the values that generator produces are only "random enough" if you don't touch the state yourself in between.

For example you could do:

int getRandomValue()
{
    srand(time(0));
    return rand();
}

and then if you call that function repeatedly so that time() returns the same values in adjacent calls you just get the same value generated - that's by design.

Related Questions

Sponsored Content

26 Answered Questions

[SOLVED] Do I cast the result of malloc?

  • 2009-03-03 10:13:02
  • Patrick McDonald
  • 218300 View
  • 2326 Score
  • 26 Answer
  • Tags:   c malloc casting

10 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

15 Answered Questions

[SOLVED] Why does this code using random strings print "hello world"?

  • 2013-03-03 04:38:06
  • 0x56794E
  • 194779 View
  • 1736 Score
  • 15 Answer
  • Tags:   java string random

18 Answered Questions

[SOLVED] With arrays, why is it the case that a[5] == 5[a]?

10 Answered Questions

8 Answered Questions

[SOLVED] Why does rand() + rand() produce negative numbers?

  • 2015-06-13 17:15:39
  • badmad
  • 41369 View
  • 302 Score
  • 8 Answer
  • Tags:   c random

4 Answered Questions

[SOLVED] How does srand relate to rand function?

  • 2014-01-22 03:21:55
  • Arrow
  • 35382 View
  • 19 Score
  • 4 Answer
  • Tags:   c random srand

5 Answered Questions

[SOLVED] How does calling srand more than once affect the quality of randomness?

  • 2014-11-30 02:10:54
  • user3920237
  • 3031 View
  • 6 Score
  • 5 Answer
  • Tags:   c++ random srand

4 Answered Questions

[SOLVED] Usefulness of `rand()` - or who should call `srand()`?

  • 2014-10-10 07:33:05
  • Albert
  • 2641 View
  • 46 Score
  • 4 Answer
  • Tags:   c++ c random srand

3 Answered Questions

[SOLVED] random numbers and multiple srand calls

  • 2012-11-26 01:11:49
  • cegfault
  • 2158 View
  • 6 Score
  • 3 Answer
  • Tags:   c random srand

Sponsored Content