Get random number in C [20+ functions]

In this article, we have explored 20+ functions in C Programming Language that is used to generate random numbers.

Table of contents:

  1. Basics of Generating random number in C
  2. rand(), srand()
  3. random(), srandom()
  4. rand_r(), random_r(), srandom_r()
  5. drand48, erand48, lrand48, nrand48, mrand48, jrand48, srand48, seed48, lcong48

Basics of Generating random number in C

A standard random number generator function in C has the following properties:

  • For a given seed value, the function generates same sequence of random numbers.
  • Random numbers lie between 0 and RAND_MAX
  • For 32 bit integer, RAND_MAX is set to 231-1.
  • Setting different seed values (like to current time) makes the function generate unique random numbers.
  • All functions generate pseudo-random numbers. There exist no function to generate pure random numbers.

Generating good random numbers is critical and is used in several pseudo-random algorithms, stimulations and much more. There are several alternatives in C Programming Language to generate random numbers.

There are different functions in C that can be used to generate random numbers such as:

  • rand(), srand()
  • random(), srandom()
  • rand_r(), random_r(), srandom_r()
  • drand48, erand48, lrand48, nrand48, mrand48, jrand48, srand48, seed48, lcong48

rand(), srand()

  • srand() is used to set a seed value for rand() function. This is set only once for a given program. If we set the same seed value, same sequence of pseudo-random numbers are generated. As a practice, seed value is set to current time for maximum randomness.
  • rand() returns a number between 0 and RAND_MAX.347069695

Example C implementation using rand() and srand():

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

int main() {
	srand(time(NULL));
    int r = rand();
    printf("Random number: %d", r);
	return 0;
}

Output:

Random number: 347069695

To generate a random number between 0 and 100, use the following code snippet:

int r = rand() % 101;

To generate a random number between 15 and 120, use the following code snippet:

int r = 15 + rand() % 121;

random(), srandom()

random() function is the more portable version of rand(). Both functions use the same pseudo-random number generator. On newer C implementations, the lower bits are less random in case of rand() compared to random(). The higher bits are equally random. So, random() should be used instead of rand().

Example C implementation using random() and srandom():

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

int main() {
	srandom(time(NULL));
    int r = random();
    printf("Random number: %d", r);
	return 0;
}

Output:

Random number: 377644180

rand_r(), random_r(), srandom_r()

random_r() function is a modification of random() function where the persistent state is stored in a memory area that is managed by the program directly instead of the system. This is useful when we want to generate random number quickly without synchronizing PRNG state in a multi-threaded environment.

Similarly, rand_r() is a modification of rand().

Similarly, for the seed function, srandom_r() and srand_r() is a modification of srandom() and srand() respectively.

The function definition is as follows:

int random_r(struct random_data *buf, int32_t *result);

int srandom_r(unsigned int seed, struct random_data *buf);

Example C implementation using random_r() and srandom_r():

#include <pthread.h>
#include <stdlib.h>
#define NTHREADS 4
#define PRNG_BUFSZ 32

void* thread_run(void* arg) {
    int r1;
    random_r((struct random_data*)arg, &r1);
}

int main(int argc, char** argv) {
    struct random_data* rand_states;
    char* rand_statebufs;
    pthread_t* thread_ids;
    int t = 0;
    rand_states = (struct random_data*)calloc(NTHREADS, sizeof(struct random_data));
    rand_statebufs = (char*)calloc(NTHREADS, PRNG_BUFSZ);
    thread_ids = (pthread_t*)calloc(NTHREADS, sizeof(pthread_t));
    
    /* create threads */
    for (t = 0; t < NTHREADS; t++) {
        /* Each thread, initialize a PRNG (the seed is the first argument) */
        initstate_r(random(), &rand_statebufs[t], PRNG_BUFSZ, &rand_states[t]);
        pthread_create(&thread_ids[t], NULL, &thread_run, &rand_states[t]);
    }
    for (t = 0; t < NTHREADS; t++) {
        pthread_join(thread_ids[t], NULL);
    }
    free(thread_ids);
    free(rand_states);
    free(rand_statebufs);
}

drand48, erand48, lrand48, nrand48, mrand48, jrand48, srand48, seed48, lcong48

drand48 and erand48 are C functions that generate non-negative double precision random numbers of uniform distribution. The range is [0.0, 1.0). erand48 does not need a seed function while drand48 depends on the seed function srand48.

lrand48 and nrand48 return non-negative random integers of data-type long int and is uniformly distributed between 0 and 231. nrand48 does not need a seed function while lrand48 depends on the seed function srand48.

mrand48 and jrand48 generates signed long random integers which are uniformly distributed between -231 and 231. jrand48 does not need a seed function while mrand48 depends on the seed function seed48.

These random function follow the linear congruential formula:

XN+1 = (a * XN + c) mod m when N>=0

By default, the value of a and c are as follows: a = 0x5DEECE66D and c = 0xB. Custom values of a and c can be set using lcong48(). The function signature is:

void lcong48(unsigned short param[7]);

lcong48 has 7 parameters: parameter[0-2] = Xi parameter[3-5] = a parameter[6] = c A call to srand48 or seed48 initializes the values Xi, a and c to the default values.

Example C implementation using srand48() and drand48():

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

int main() {
	srand48(time(NULL));
    double r = drand48();
    printf("Random number: %f", r);
	return 0;
}

Output:

Random number: 0.769060

Example C implementation using lcong48() and drand48():

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

int main() {
    unsigned short parameters[7] = {19, 3, 5, 0, 2, 4, 9};
	lcong48(parameters);
    double r = drand48();
    printf("Random number: %f", r);
	return 0;
}

Output:

Random number: 0.001251

With this article at OpenGenus, you must have the complete idea of generating the perfect random number for your C application.