Introduction to generating random Numbers in C programming

  • 2020-05-07 20:06:36
  • OfStack

Generating random Numbers in a language is one of the most common programming tasks, and of course it's not that hard to do, just call two or three functions, but do you know exactly what those functions do and how they generate random Numbers?

several concepts

Random Numbers: the mathematical generation is pseudorandom Numbers, real random Numbers using physical methods.

Random number seed: the generation of random Numbers is generated by arithmetic rules. The random number seed of srand(seed) is different, and the random value of rand() is different. If the random number seed of srand(seed) is 1, the value of rand() is 1. So to generate a random number, the random number seed of srand(seed) must also be random.

generates a random number seed with srand()

Prototype: void srand (unsigned int seed);

The function is to set the random number seed, in order for the random number seed to be random, time(NULL) value is usually used for seed.


time() is used for random number seed

Function prototype: time_t time (time_t * timer);

The time() function represents the number of seconds returned from 1970-1-1 00:00:00 to the current time.

srand(unsigned(time(NULL))); For example, generate random integers between 1 and 10


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

int main()
{
  srand(time(NULL));
  for(int i=0;i < 10;i++)
  {
    int randValue=rand()%10;
  }
}

Note in the above program that srand is outside the for loop. If you put srand inside the for loop, you will generate the same random number each time.

generates a random number with rand()

Prototype: int rand (void);

The function is to generate 1 random number. Of course, the random number has a range, ranging from 0 to RAND_MAX. The random number is related to the random number seed. Specifically, when the random number rand() is called, it does this:

If the user previously called srand(seed), he will call srand(seed) again once to generate a random number seed.
If you find that srand(seed) has not been called, srand(1) is automatically called once.
If the random number seed generated by calling srand(seed) is 1 (that is, seed has the same value), rand() generates the same random number.
So if you want rand() to produce a different value every time you call it, you need to call srand(seed) once, and seed cannot be the same. This is why time(NULL) is often used to generate random number seeds.

The rand() function can be used in C to generate an uniform distribution from 0 to RAND_MAX. Based on this function, we can construct some specific random number generators to meet our needs.
(1) uniform distribution from 0 to 1:


//generate a random number in the range of [0,1]
double uniform_zero_to_one(){
  return (double)rand()/RAND_MAX;
}

(2) uniform distribution of any real number interval:


//generate a random real number in [start,end]
double uniform_real(double start,double end){
  double rate=(double)rand()/RAND_MAX;
  return start+(end-start)*rate;
}

(3) uniform distribution of any integer interval:


//generate a random integer number in [start,end)
int uniform_integer(int start,int end){
  int base=rand();
  if(base==RAND_MAX)
    return uniform_integer(start,end);
  int range=end-start;
  int remainder=RAND_MAX%range;
  int bucket=RAND_MAX/range;
  if(base<RAND_MAX-remainder)
    return start+base/bucket;
  else
    return uniform_integer(start,end);
}

This function to specify 1, normally when we are using rand () % n to generate random Numbers 0 to n - 1, but distribution generated by this method is not uniform, also RAND_MAX by only 32767, so to generate greater than the number of random number need to think of some way to another, in theory, can be directly from 0 to 1 uniform distribution scale directly, but the actual effect is not good. This paper presents the implementation of one shift mode.

(4) random number of 32bits


//generate a random 32 bits integer number 
int rand32(){
  return ((rand()<<16)+(rand()<<1)+rand()%2);
}

With 32bits's random number generation method, it is possible to construct random integer intervals in the range of 32bits, as in the previous case of 16bits.

(5) random integer interval within the range 32bits


//generate a random 32bits integer number in [start,end)
 int uniform_integer_32(int start,int end){
   int base=rand32();
  if(base==RAND32_MAX)
    return uniform_integer_32(start,end);
  int range=end-start;
  int remainder=RAND32_MAX%range;
  int bucket=RAND32_MAX/range;
  if(base<RAND32_MAX-remainder)
    return start+base/bucket;
  else
    return uniform_integer_32(start,end);
}

Here RAND32_MAX is defined as 0x7fffffff.

In addition, rand() function is also used to construct random Numbers with arbitrary distribution.

Theoretically, it can be obtained by the uniform distribution of (0,1), plus the standard sampling method (sampling).


Related articles: