Published by
Jan 17, 2012 (last update: Jan 17, 2012)

Random number generator

Score: 4.1/5 (1007 votes)
*****

Random Number Generation:


Let's dive into a hopefully entertaining topic which is random number generation provided by the C standard library.
First of all why would we need to generate random numbers in our programs?
I believe that these numbers are really helpful in simulation and games.

C provides random number generation function rand() that is found in <stdlib.h> header.

consider the following C statement:

 
i = rand();


The rand function generates an integer between 0 and RAND_MAX
(a constant defined in the <stdlib.h> header).
Standard C states that the value of RAND_MAX must be at least 32767, which is the maximum value for a two-byte (i.e., 16-bit) integer.

The value of the RAND_MAX differs from one compiler to another you can check the exact value of the RAND_MAX for your compiler simply by the following code.

1
2
3
4
5
6
7
8
#include <stdlib.h>
#include <stdio.h>
/* function main begins program execution */
int main() {

	printf("%d", RAND_MAX);
	return 0; /* indicates successful termination */
} /* end main */


On my GNU C compiler the RAND_MAX was:


2147483647

And on my Visual C++ compiler the RAND_MAX was:


32767

There is an equal probability (chance) that each number from 0 to RAND_MAX gets chosen each time rand function is called.
The range of values produced directly by rand is often different from what is needed in a specific application.
For example:
  • A game that has coins tossed by the computer needs to have 2 values lets say either a 0 or 1.
  • A game that has a dice with 6 faces and the computer has to throw the dice for the player to get a number from 1 to 6

    • To demonstrate rand, let’s develop a program to simulate 20 rolls of a six-sided die and print the value of each roll. The function prototype for function rand is in <stdlib.h>.
      We use the remainder operator (%) with rand as follows:
       
      rand() %6

      to produce integers from 0 to 5 and this is called scaling the number 6 is called the the scaling factor.
      We then shift the range of numbers produced by adding 1 to our previous result.

      Here is the complete program:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      #include <stdio.h>
      #include <stdlib.h>
      /* function main begins program execution */
      int main(void) {
      	int i; /* counter */
      	/* loop 20 times */
      	for (i = 1; i <= 20; i++) {
      		/* pick random number from 1 to 6 and output it */
      		printf("%d ", 1 + (rand() % 6));
      		/* if counter is divisible by 5, begin new line of output */
      		if (i % 5 == 0) {
      			printf("\n");
      		} /* end if */
      	} /* end for */
      	return 0; /* indicates successful termination */
      } /* end main */


      The output of these numbers differ from one compiler to another remember it is supposed to be random but here is the output I got:

      
      2 5 4 2 6
      2 5 1 4 2
      3 2 3 2 6
      5 1 1 5 5
      
      

      To show that these numbers occur approximately with equal likelihood, let’s simulate 6000 rolls of a die with the program above so we should say that each number from 1 to 6 should appear approximatly 1000 times.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      #include <stdio.h>
      #include <stdlib.h>
      /* function main begins program execution */
      int main(void) {
      	int frequency1 = 0; /* rolled 1 counter */
      	int frequency2 = 0; /* rolled 2 counter */
      	int frequency3 = 0; /* rolled 3 counter */
      	int frequency4 = 0; /* rolled 4 counter */
      	int frequency5 = 0; /* rolled 5 counter */
      	int frequency6 = 0; /* rolled 6 counter */
      	int roll; /* roll counter, value 1 to 6000 */
      	int face; /* represents one roll of the die, value 1 to 6 */
      	/* loop 6000 times and summarize results */
      	for (roll = 1; roll <= 6000; roll++) {
      		face = 1 + rand() % 6; /* random number from 1 to 6 */
      		/* determine face value and increment appropriate counter */
      		switch (face) {
      		case 1: /* rolled 1 */
      			++frequency1;
      			break;
      		case 2: /* rolled 2 */
      			++frequency2;
      			break;
      		case 3: /* rolled 3 */
      			++frequency3;
      			break;
      		case 4: /* rolled 4 */
      			++frequency4;
      			break;
      		case 5: /* rolled 5 */
      			++frequency5;
      			break;
      		case 6: /* rolled 6 */
      			++frequency6;
      			break; /* optional */
      		} /* end switch */
      	} /* end for */
      	/* display results in tabular format */
      	printf("%s%13s\n", "Face", "Frequency");
      	printf("1%13d\n", frequency1);
      	printf("2%13d\n", frequency2);
      	printf("3%13d\n", frequency3);
      	printf("4%13d\n", frequency4);
      	printf("5%13d\n", frequency5);
      	printf("6%13d\n", frequency6);
      	return 0; /* indicates successful termination */
      } /* end main */


      
      Face    Frequency
      1          980
      2          993
      3         1030
      4         1009
      5         1002
      6          986
      
      


      Of course I could have made that code much smaller and more elegant using an array containing the 6 heads for the dice but I am trying to make the codes as simple as possible for beginner C programmers as well.

      So we see that each face was chosen nearly 1000 times.

      Notice that there is a problem with the above programs is that if you run any of the above programs again you will find that it produces the same numbers and I am going to explain this in the next section.


      Function rand actually generates pseudorandom numbers. Calling rand repeatedly
      produces a sequence of numbers that appears to be random.
      However, the sequence repeats itself each time the program is executed this can help you debug your program that uses rand function.
      Once a program has been thoroughly debugged, it can be conditioned to produce a different sequence of random numbers for each execution.
      This is called randomizing and is and that can be done using the standard library function srand.
      Function srand takes an unsigned integer as a parameter and seeds function rand to produce a different sequence of random numbers for each execution of the program.

      I do explain how to use srand function in the next example code:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      #include <stdlib.h>
      #include <stdio.h>
      
      /* function main begins program execution */
      int main(void) {
      	int i; /* counter */
      	unsigned seed; /* number used to seed random number generator */
      
      	printf("Enter seed: ");
      	scanf("%u", &seed); /* note %u for unsigned */
      
      	srand(seed); /* seed random number generator */
      	/* loop 10 times */
      	for (i = 1; i <= 10; i++) {
      
      		/* pick a random number from 1 to 6 and output it */
      		printf("%10d", 1 + (rand() % 6));
      
      		/* if counter is divisible by 5, begin a new line of output */
      		if (i % 5 == 0) {
      			printf("\n");
      		} /* end if */
      	} /* end for */
      
      	return 0; /* indicates successful termination */
      } /* end main */
      


      Here are 3 different runs of the program:

      
      Enter seed:3
               1         3         1         2         6
               4         3         2         2         1
      

      
      Enter seed:200
               2         1         5         6         1
               2         2         5         3         5
      

      
      Enter seed:3
               1         3         1         2         6
               4         3         2         2         1
      

      Note that when I re-entered the number 3 again in the last run it produced the same numbers as the first run because the seed values are equal.
      Now if we want to randomize using a seed but not have to enter the seed each time we execute the program we can write something like this:

      srand( time( NULL ) );
      This causes the computer to read its clock to obtain the value for the seed automatically.
      Function time returns the number of seconds that have passed since midnight on January 1, 1970. This value is converted to an unsigned integer and used as the seed to the random number generator.
      Function time takes NULL as an argument and it is found in the header time.h

      Now it is time for the final step in our dice rolling program is to randomize the numbers without having to enter the seed.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      #include <stdlib.h>
      #include <stdio.h>
      #include <time.h>
      
      /* function main begins program execution */
      int main(void) {
      	int i; /* counter */
      
      	srand(time(NULL)); /* seed random number generator */
      	/* loop 10 times */
      	for (i = 1; i <= 10; i++) {
      
      		/* pick a random number from 1 to 6 and output it */
      		printf("%10d", 1 + (rand() % 6));
      
      		/* if counter is divisible by 5, begin a new line of output */
      		if (i % 5 == 0) {
      			printf("\n");
      		} /* end if */
      	} /* end for */
      
      	return 0; /* indicates successful termination */
      } /* end main */


      Each time you execute this program you will find a different sequence here is a two executions:

      
               4         4         3         6         6
               2         6         4         3         3
      

      
              2         6         3         4         3
              3         5         4         5         6
      

      If you need any help in C/C++ you can contact me via:
      Twitter: _mFouad
      By mail: mfouad91@gmail.com