Why do I always get the same sequence of random numbers with rand()?

Solution 1:

You have to seed it. Seeding it with the time is a good idea:

srand()

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main ()
{
  srand ( time(NULL) );
  printf ("Random Number: %d\n", rand() %100);
  return 0;
}

You get the same sequence because rand() is automatically seeded with the a value of 1 if you do not call srand().

Edit

Due to comments

rand() will return a number between 0 and RAND_MAX (defined in the standard library). Using the modulo operator (%) gives the remainder of the division rand() / 100. This will force the random number to be within the range 0-99. For example, to get a random number in the range of 0-999 we would apply rand() % 1000.

Solution 2:

rand() returns pseudo-random numbers. It generates numbers based on a given algorithm.

The starting point of that algorithm is always the same, so you'll see the same sequence generated for each invocation. This is handy when you need to verify the behavior and consistency of your program.

You can set the "seed" of the random generator with the srand function(only call srand once in a program) One common way to get different sequences from the rand() generator is to set the seed to the current time or the id of the process:

srand(time(NULL)); or srand(getpid()); at the start of the program.

Generating real randomness is very very hard for a computer, but for practical non-crypto related work, an algorithm that tries to evenly distribute the generated sequences works fine.

Solution 3:

To quote from man rand :

The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand() with the same seed value.

If no seed value is provided, the rand() function is automatically seeded with a value of 1.

So, with no seed value, rand() assumes the seed as 1 (every time in your case) and with the same seed value, rand() will produce the same sequence of numbers.

Solution 4:

There's a lot of answers here, but no-one seems to have really explained why it is that rand() always generates the same sequence given the same seed - or even what the seed is really doing. So here goes.

The rand() function maintains an internal state. Conceptually, you could think of this as a global variable of some type called rand_state. Each time you call rand(), it does two things. It uses the existing state to calculate a new state, and it uses the new state to calculate a number to return to you:

state_t rand_state = INITIAL_STATE;

state_t calculate_next_state(state_t s);
int calculate_return_value(state_t s);

int rand(void)
{
    rand_state = calculate_next_state(rand_state);
    return calculate_return_value(rand_state);
}

Now you can see that each time you call rand(), it's going to make rand_state move one step along a pre-determined path. The random values you see are just based on where you are along that path, so they're going to follow a pre-determined sequence too.

Now here's where srand() comes in. It lets you jump to a different point on the path:

state_t generate_random_state(unsigned int seed);

void srand(unsigned int seed)
{
    rand_state = generate_random_state(seed);
}

The exact details of state_t, calculate_next_state(), calculate_return_value() and generate_random_state() can vary from platform to platform, but they're usually quite simple.

You can see from this that every time your program starts, rand_state is going to start off at INITIAL_STATE (which is equivalent to generate_random_state(1)) - which is why you always get the same sequence if you don't use srand().