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:
- Basics of Generating random number in C
- rand(), srand()
- random(), srandom()
- rand_r(), random_r(), srandom_r()
- 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.