Lesson 8.8. Random numbers in C

Standard C libraries

Most C compilers come with a collection of standard, standardized libraries containing common operations (display, math calculations, reading and writing to files ...). These libraries mainly contain functions which can be used by including the header of the library concerned. For example, to use the printf()`` function, you must include thestdio.h` library:

#include <stdio.h>

stdlib.h

The sdtlib.h library contains various basic functions (memory allocation, conversion of variables ...). The functions we'll focus one here are the srand () and rand () functions which generate random numbers (or more exactly pseudo-random numbers, but we will come back to that).

We will focus on the following elements of the stdlib.h library:

// Symbolic constant
#define RAND_MAX
// Functions
int rand(void);
void srand(unsigned int seed);

Random numbers

The rand () function generates a pseudo-random number between 0 and RAND_MAX. RAND_MAX is a symbolic constant (or macro) defined instdlib.h. This constant contains the maximum value returned by the rand () function.

Here is a basic example:

// Displays the maximum value of the pseudo-random generator
printf ("Maximum value: %d\n", RAND_MAX);

// Pick two random numbers
printf ("A random number: %d\n", rand());
printf ("Another random number: %d\n", rand());

If you run the above code multiple times, you will find that it always draw the same numbers.

Pseudorandom numbers

A processor is a deterministic machine which cannot generate real random numbers, moreover the general notion of randomness remains debatable. The numbers generated by the rand () function are [pseudo-random numbers] (https://en.wikipedia.org/wiki/Pseudorandom_number_generator) A pseudo-random algorithm generates a sequence of numbers which have certain properties, such as equiprobability. If the previous program still picks the same numbers, it is because they are the first of the sequence. Function srand () for seed random allows to define the seed generator and thus modify the starting point of the sequence. To avoid always picking the same random numbers, we conventionally use the current time as seed of the generator:

#include <stdlib.h>
#include <time.h>
// Initialize the seed of the pseudorandom generator
srand(time(NULL));

Now, on each run (at least one second apart from the previous one) the program displays different numbers.

Pick a random number in an interval

Most of the time, we need to pick numbers in a given interval. If we wish picking a number between 0 and max, the best solution is to use the rest of the integer division (modulo %):

// x is a pseudirandom number between 0 and max included
int x = rand() % (max+1);

If you want a lower bound, you have to shift the draw by adding the bound inferior :

// x is a pseudorandom number between min and max included
int x = min + rand() % (max + 1 - min);

Picking a random floating point number

It is also common to have to pick a real number. The trick is to divide the number generated by RAND_MAX, and thus obtain a result between 0 and 1:

// x is a random floating point number between 0 et 1
float x = (float)rand()/(float)(RAND_MAX);

Note the change of type (cast int ->float) in order to perform the division on floating. By dividing RAND_MAX by the boundmax, we can obtain the drawing a real number between 0 and max:

// x is a pseudorandom floating point number between 0 and max
float x = (float)rand() / ((float)RAND_MAX/max);

Finally, by shifting the interval, we get a floating point number in the interval [min; max] as seen previously:

// x is a pseudorandom floating point number between min and max
float x = min + (float)rand() / ((float)RAND_MAX/(max-min));

Exercises

Exercise 1

Write a program that simulates the draw of two 6-sided dice:

Dace 1 : 6
Dace 2 : 1

Exercise 2

To assess students, a teacher needs 24 grades in the range [0; 20]. Write a program that generates these 24 notes:

Grade #1 : 9.2
Grade #2 : 13.1
Grade #3 : 1.1
Grade #4 : 13.2
...
Grade #21 : 17.5
Grade #22 : 18.4
Grade #23 : 19.7
Grade #24 : 15.7

Exercise 3

Write a function rangedom(int a, int b) which pick an integer in the interval [a; b]. Draw and display 100 random numbers between 8 and 12 included:

8 9 8 11 9 9 12 12 8 8 8 12 12 11 10 11 12 10 11 11 8 11 10 11 10 9 8 10 10 10 12 
10 8 9 8 9 10 10 8 12 10 10 9 9 8 11 10 10 10 10 8 10 8 8 11 12 11 8 11 8 12 10 11 
12 8 11 8 12 10 10 12 10 8 8 11 10 8 10 9 11 12 10 10 9 12 10 9 10 11 12 11 10 12 
9 10 9 9 10 9 12

Exercise 4

Write a randFloat() function that pick a pseudo-random number between 0 and 1. Pick one million numbers and display the average. The average should be close to 0.5:

Average = 0.5003

Quiz

Are the standard libraries supplied with all C compilers?

Check Well done! Try again...

Are the standard C libraries compatible from one compiler to another?

Check Well done! Try again...

What really does a pseudo-random generator?

Check Well done! Try again...

What is this line of code for?

srand(time(NULL));
Check Well done! Try again...

What does the following code do?

x = 5 + rand()%10;
Check Well done! Try again...

See also


Last update : 12/07/2022