Generating random numbers in C

While searching for Tutorials on generating random numbers in C I found this topic

When I try to use the rand() function without parameters, I always get 0. When I try to use the rand() function with parameters, I always get the value 41. And whenever I try to use arc4random() and random() functions, I get a LNK2019 error.

Here's what I've done:

#include <stdlib.h>
int main()
{
  int x;
  x = rand(6);
  printf("%d", x);
}

This code always generates 41. Where am I going wrong? I'm running Windows XP SP3 and using VS2010 Command Prompt as compiler.


Solution 1:

You should call srand() before calling rand to initialize the random number generator.

Either call it with a specific seed, and you will always get the same pseudo-random sequence

#include <stdlib.h>

int main ()
{
  srand ( 123 );
  int random_number = rand();
  return 0;
}

or call it with a changing sources, ie the time function

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

int main ()
{
  srand ( time(NULL) );
  int random_number = rand();
  return 0;
}

In response to Moon's Comment rand() generates a random number with an equal probability between 0 and RAND_MAX (a macro pre-defined in stdlib.h)

You can then map this value to a smaller range, e.g.

int random_value = rand(); //between 0 and RAND_MAX

//you can mod the result
int N = 33;
int rand_capped = random_value % N;  //between 0 and 32
int S = 50;
int rand_range = rand_capped + S; //between 50 and 82

//you can convert it to a float
float unit_random = random_value / (float) RAND_MAX; //between 0 and 1 (floating point)

This might be sufficient for most uses, but its worth pointing out that in the first case using the mod operator introduces a slight bias if N does not divide evenly into RAND_MAX+1.

Random number generators are interesting and complex, it is widely said that the rand() generator in the C standard library is not a great quality random number generator, read (http://en.wikipedia.org/wiki/Random_number_generation for a definition of quality).

http://en.wikipedia.org/wiki/Mersenne_twister (source http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html ) is a popular high quality random number generator.

Also, I am not aware of arc4rand() or random() so I cannot comment.

Solution 2:

You need to seed your PRNG so it starts with a different value each time.

A simple but low quality seed is to use the current time:

srand(time(0));

This will get you started but is considered low quality (i.e. for example, don't use that if you are trying to generate RSA keys).

Background. Pseudo-random number generators do not create true random number sequences but just simulate them. Given a starting point number, a PRNG will always return the same sequence of numbers. By default, they start with the same internal state so will return the same sequence.

To not get the same sequence, you change the internal state. The act of changing the internal state is called "seeding".