Random Numbers

Generating Random Numbers in C

  • Computers can't generate truly random numbers; they generate pseudo-random numbers.
  • Random numbers are used extensively to test programs; easier than typing input from the keyboard all day.
  • Used in many simulations (e.g. games) to add a sense of "chance" to the program.
  • Computers have built-in algorithms that produce pseudo-random numbers for programs to use.
  • One method of accessing these numbers is to call the C library function rand() which will return a random integer between 0 and 32,767 (or larger, depending on the compiler).
  • To use the rand() function, you need to include stdlib.h. Example:
    #include <stdio.h>  /* printf */
    #include <stdlib.h> /* rand   */
    
    int main(void)
    {
      int i;
      
      for (i = 0; i < 10; i++)
        printf("%i\n", rand());
        
      return 0;
    }
    Output:
    MicrosoftBorlandGNU gcc
    41
    18467
    6334
    26500
    19169
    15724
    11478
    29358
    26962
    24464
    
    130
    10982
    1090
    11656
    7117
    17595
    6415
    22948
    31126
    9004
    
    0
    1481765933
    1085377743
    1270216262
    1191391529
    812669700
    553475508
    445349752
    1344887256
    730417256
    

    Constraining and Seeding the Pseudo-Random Number Generator

    Usually, we want to generate random numbers within a specific range, rather than between 0 and 32,767 (or 2,147,483,647). The modulus operator, %, is very handy for this. This example generates 5 numbers between 1 and 10:

    #include <stdio.h>  /* printf */
    #include <stdlib.h> /* rand   */
    
    int main(void)
    {
      int i;
      
      for (i = 0; i < 10; i++)
        printf("%i\n", rand() % 10 + 1);
        
      return 0;
    }
    Output:
    MicrosoftBorlandGNU gcc
    2
    8
    5
    1
    10
    5
    9
    9
    3
    5
    
    1
    3
    1
    7
    8
    6
    6
    9
    7
    5
    
    1
    4
    4
    3
    10
    1
    9
    3
    7
    7
    

    If I run the program 5 times, this is the output of the 5 runs: (each column is a run). See a problem?

     2    2    2    2    2
     8    8    8    8    8
     5    5    5    5    5
     1    1    1    1    1
    10   10   10   10   10
     5    5    5    5    5
     9    9    9    9    9
     9    9    9    9    9
     3    3    3    3    3
     5    5    5    5    5
    
    Issues with the pseudo-random number generator:
    #include <stdio.h>  /* printf      */
    #include <stdlib.h> /* rand, srand */
    
    int main(void)
    {
      int i; 
      
      srand(0);
      printf("srand(0): ");
      for (i = 0; i < 10; i++)
        printf("%i  ", rand());
      printf("\n");
    
      srand(1);
      printf("srand(1): ");
      for (i = 0; i < 10; i++)
        printf("%i  ", rand());
      printf("\n");
    
      srand(2);
      printf("srand(2): ");
      for (i = 0; i < 10; i++)
        printf("%i  ", rand());
      printf("\n");
    
      srand(2);
      printf("srand(2): ");
      for (i = 0; i < 10; i++)
        printf("%i  ", rand());
      printf("\n");
    
      srand(1);
      printf("srand(1): ");
      for (i = 0; i < 10; i++)
        printf("%i  ", rand());
      printf("\n");
    
      return 0;
    }
    Compiled with Microsoft's compiler:
    srand(0): 38  7719  21238  2437  8855  11797  8365  32285  10450  30612
    srand(1): 41  18467  6334  26500  19169  15724  11478  29358  26962  24464
    srand(2): 45  29216  24198  17795  29484  19650  14590  26431  10705  18316
    srand(2): 45  29216  24198  17795  29484  19650  14590  26431  10705  18316
    srand(1): 41  18467  6334  26500  19169  15724  11478  29358  26962  24464
    

    Of course, this leads to the same problem: how do we randomly choose the position in the list? The computer doesn't really do anything randomly. So we improvise:

    #include <stdio.h>  /* printf      */
    #include <stdlib.h> /* rand, srand */
    #include <time.h>   /* time        */
    
    int main(void)
    {
      int i;
      
      srand(time(0));
      for (i = 0; i < 10; i++)
        printf("%i  ", rand());
        
      return 0;
    }
    Running the program 5 times gives these outputs: (compiled with gcc)
    1384334524  735471424  1860098722  694496962  1657646138  301995943  1803857288  1201859531  1067245105  2108720089
    2135987043  1232099519  337709210  1659609624  271785989  709050360  181970958  1810020192  440129707  1154963843
    1470269329  835711329  522547729  1580784891  2040547807  449856168  73845202  562074047  1973143356  89221058
    804551614  439323139  707386248  1501960159  1661825977  190661976  2113203095  1461611550  1358673356  1170961921
    954882118  1397642217  1261901805  1265485962  525660488  1560563048  1788825829  2012740412  1662747006  121217212
    
    A note about the time function:

    Putting a "Wrapper" Function Around rand()

    Although using the modulo operator, %, is simple and effective, it can be tedious and error-prone to use it to constrain the random numbers. A better solution is to write your own function that does all of the work for you.

    This simple function takes two parameters which specify a range (inclusive) that the random number should be within:

    int RandomInt(int low, int high)
    {
      int number = rand() % (high - low + 1) + low;
      return number;
    }
    
    Sample program:
    #include <stdio.h>  /* printf      */
    #include <stdlib.h> /* rand, srand */
    #include <time.h>   /* time        */
    
    int RandomInt(int low, int high)
    {
      int number;
      number = rand() % (high - low + 1) + low;
      return number;
    }
    
    int main(void)
    {
      int i;
      
      srand(time(0)); /* seed PRNG */
    
        /* 10 numbers between 10 and 20   */
      for (i = 0; i < 10; i++)
        printf("%3i  ", RandomInt(10, 20));
      printf("\n");
    
        /* 10 numbers between 100 and 200 */
      for (i = 0; i < 10; i++)
        printf("%3i  ", RandomInt(100, 200));
      printf("\n");
    
        /* 10 numbers between -10 and 10  */
      for (i = 0; i < 10; i++)
        printf("%3i  ", RandomInt(-10, 10));
      printf("\n");
    
      return 0;
    }
    Output from running the program 5 times:
     19   14   17   15   11   19   11   19   13   14
    138  140  140  106  134  115  118  182  155  101
      6   -9   -7   -7   -9    6    5    7    5    2
    
    
     12   16   16   14   11   14   16   13   14   18
    152  148  165  176  180  130  121  119  187  193
     -6   -7   -2   -6    2    4   -4    7    1    6
    
    
     12   14   10   16   13   12   17   13   19   12
    157  143  199  159  132  193  163  136  131  178
      9   -2   -2   10   -5   -9    5   -7    2   -2
    
    
     12   14   10   16   13   12   17   13   19   12
    157  143  199  159  132  193  163  136  131  178
      9   -2   -2   10   -5   -9    5   -7    2   -2
    
    
     20   14   18   18   10   19   15   19   20   17
    169  128  197  118  144  172  189  129  190  168
     -9   -8  -10   10   -2    6    2    4    6   -4
    

    Interactive example:

    #include <stdio.h>  /* printf, scanf */
    #include <stdlib.h> /* rand, srand   */
    #include <time.h>   /* time          */
    
    int RandomInt(int low, int high)
    {
      int number;
      number = rand() % (high - low + 1) + low;
      return number;
    }
    
    int main(void)
    {
      int low, high, count, i;
    
      srand(time(0));
    
      printf("Enter lowest value: ");
      scanf("%d", &low);
    
      printf("Enter highest value: ");
      scanf("%d", &high);
    
      printf("How many numbers? ");
      scanf("%d", &count);
    
      for (i = 0; i < count; i++)
        printf("%i  ", RandomInt(low, high));
    
      printf("\n");
      return 0;
    }
    Output from running the program 4 times:
    Enter lowest value: 10
    Enter highest value: 20
    How many numbers? 10
    10  20  20  17  19  17  13  11  19  18
    
    
    Enter lowest value: -100 Enter highest value: 100 How many numbers? 100 -100 64 -46 79 -92 68 -1 -18 -25 40 -93 -13 7 89 79 20 -98 -76 56 61 -44 81 1 -29 -44 -21 -99 -82 -58 7 7 -12 -94 -38 75 98 53 19 -59 34 -84 10 41 17 95 17 -51 -70 -85 99 -3 68 -56 2 92 57 23 32 -28 -29 26 -84 -70 9 4 37 30 -65 51 40 33 22 61 17 17 -59 8 9 16 22 2 -91 22 1 41 62 -18 -50 -38 13 60 -89 88 -88 27 -69 -100 -57 69 48 -11
    Enter lowest value: 0 Enter highest value: 50 How many numbers? 10 0 50 27 11 11 0 48 4 18 50
    Enter lowest value: 10 Enter highest value: 99 How many numbers? 200 10 93 73 12 69 40 88 62 76 36 29 91 51 13 75 88 33 40 76 39 72 47 27 12 18 20 53 79 22 34 29 31 87 80 64 85 90 54 90 92 54 43 61 10 46 56 91 19 77 35 31 30 64 34 95 49 40 67 36 73 44 64 80 69 60 56 42 62 33 80 39 69 85 55 99 97 59 57 54 76 79 36 54 13 55 47 66 69 84 32 15 63 58 41 20 70 77 35 56 63 81 97 62 36 18 92 91 30 60 68 31 61 84 77 74 67 55 58 61 88 37 31 17 73 39 55 10 60 33 62 24 53 57 11 70 30 67 98 26 13 87 88 13 68 48 35 43 88 40 81 96 97 60 29 47 38 43 33 10 24 75 33 62 50 17 62 50 25 40 10 66 22 65 10 97 24 81 28 66 39 40 95 85 32 44 71 36 62 48 35 10 18 13 69 96 39 90 35 82 63

    Here is an example of a simple pseudo-random number generator: