Back to DFS's C Page


Generating Random Values

One of the major uses for computers is to simulate what happens in the real world. It is up to the programmer to write the programs that mimic what is happening around us. Fundamental to this is the ability to generate random values and take action based on these values.

Linux C provides functions called srand() and rand() so you can use random values in your programs. To use these functions, your programs should include stdlib.h:

#include <stdlib.h>

void srand(unsigned int seed)

srand() establishes a table of pseudo-random values. It needs to be called only once in your program, and this should be before your first call to rand(). The best place in your program to call srand() is in the set-up section (either at the beginning of the main() or in a function) where you initialize variables and prepare the screen for output.

If you do not call srand(), rand() will always return the same sequence of values. This is useful when you are testing/debugging your program.

To get a different sequence of values each time your program is run, you need to provide srand with a different seed each time. One method recommended is to use the system clock to obtain a seed value. This can be done in the following manner:

#include <time.h>
srand(time(NULL));

int rand(void)

rand() is a function of type int -- it returns an integer value from a default table or one set up by srand(). There are two ways that rand() can be used.

  1. The first way makes use of RAND_MAX. This symbolic constant is defined in the stdlib.h header file. According to an ANSI standard, RAND_MAX must be at least 32767, the largest value which can be stored in a signed two-byte integer. On my system, which has four-byte integers, it is defined as 2147483647 (0x7FFFFFFF). The man page states that in order to get values in the range of 1 to 10 and store them in ran, the following statement should be used:

    ran = 1 + (int) ( 10.0 * rand() / (RAND_MAX + 1.0) )

    The 1 is the low value of the set of different values.

    The 10.0 represents the real version of the number of different values which can be assigned to ran. This can be calculated using the formula

    HI - LO + 1

    Since rand() returns integer values in the range 0 to RAND_MAX the expression

    rand() / RAND_MAX

    would result in only a zero or one. To increase the number of possible values, the return value from rand() is multiplied by a real value. To ensure that there are only the desired number of values created, the divisor is increased by 1.0.

  2. The second and simpler way utilizes the modulus operator (%). To obtain any one of the values from 1 to 10, inclusive, a statement such as the following can be used.
    ran = rand() % 10 + 1;

    This can be expressed formulaically as:

    ran = rand() % (HI - LO + 1) + LO
    

    The addition of the value LO results in ran being in the range

    LO <= ran <= HI
    

    To generate either a 0 or a 1 (e.g., to simulate a coin flip) and store the result in the variable ran, you would use the statement:

    ran = rand() % 2;
    

    Given that C uses zero as the first subscript for an array, it is frequently preferable to use whole numbers instead of natural numbers. This can be expressed formulaically as:

    ran = rand() % (HI - LO + 1);
    

    Generating Non-Sequential Values

    To generate one of the odd Natural numbers less than 10 (i.e., one of the set 1, 3, 5, 7, 9), we would need to generate one of five values and then proceed to select a corresponding member of the set. This can be done by setting up a table of the correspondences and determining a mathematical relationship.

    rand() % 5ran
    01
    13
    25
    37
    49

    If the columns are treated as the traditional x and y, the relationship could be expressed as

    y = 2x + 1
    
    resulting, by simple substitution in the C statement:
    ran = 2 * rand() % 5 + 1;
    

    Generating Alphabetic Characters

    For some situations, you may want to generate one of the letters of the alphabet.

    char ranletter;
    
    ranletter = 'a' + rand() % 26;
    
    The above statement starts with the char a and uses the value generated by rand() % 26 as an offset into the set of values used to represent the lowercase letters in the ASCII character set. N.B. This will not work if the system is using EBCDIC.

    Or you may want to generate just one of the lowercase vowels. This can be accomplished in a number of ways, one of which follows.

    char ranvowel;
    
    switch ( rand() % 5 )
    {
       case 0: ranvowel = 'a'; break;
       case 1: ranvowel = 'e'; break;
       case 2: ranvowel = 'i'; break;
       case 3: ranvowel = 'o'; break;
       case 4: ranvowel = 'u'; break;
    }
    

    Back to Top


    © 2000 DFStermole
    Created 26 Dec 00