VIEWS: 11 PAGES: 5 POSTED ON: 11/30/2010 Public Domain
C Programming Tips: Random Numbers This notes covers generating and using random numbers in C. C provides a library function, rand that generates random integers between 0 and RAND_MAX, a system dependent maximum. We'll learn how to use the rand function and how to modify its output in useful ways. A second system function, srand, is used to set the initial seed used to generate the random numbers. Simple put, if different initial seeds are used, different sequence of random numbers are generated; same seed, same sequences. We will also cover some common uses of pseudorandom numbers. We'll see how to scale the generated numbers within an inclusive range, from 1 to N. As an aside, random numbers generated by computers are more correctly called Pseudorandom numbers. They are not truly random, like flipping a coin, but are generated through mathematics algorithms. For most simple uses, the results from the rand function are random enough, but individual library implementations vary. RAND_MAX The function, rand, is used to generate a random integer between 0 and RAND_MAX. Rand is part of the C standard library. Let's discuss RAND_MAX. This number is system dependent and is located within stdlib.h. Determining its value is simple, as shown in the following example. #include <stdio.h> #include <stdlib.h> int main() { printf("%d\n",RAND_MAX); return 0; } Rand and Srand As stated earlier, rand returns a random integer between 0 and RAND_MAX. Let's look at a simple program to better understand its use. #include <stdio.h> #include <stdlib.h> int main() { int i; for (i = 0; i < 5; i++) { printf("%d\n",rand()); } return 0; } Here's the output from two runs. RUN 1 RUN 2 Notice that the results are identical. That is because the initial seed used is identical each time. The seed is used to kick off the sequence of random numbers. It is explicitly specified using the srand function. Getting the same sequence for every run can be useful for testing and in some situations, but it usually isn't what is wanted. Srand takes an unsigned int as an argument and sets the seed used for generating random numbers. Usually, the system time is a good choice as an argument for srand. It will be different each time the program is run. Thus, results will also be different. #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i; /* Set evil seed (initial seed) */ srand( (unsigned)time( NULL ) ); for (i = 0; i < 5; i++) { printf("%d\n",rand()); } return 0; } Scaling Random Numbers To A Range The random integers returned by rand can be mapped into other distributions, such as Gaussian or Exponential, but the mathematics required for this are beyond the scope of this course. Let's looks at two simple cases. The first example will show how to generate a uniform distribution, that is, floating point numbers from 0 to 1. Second, we map the integers returned by rand to a range from 1 to N, where N is less than RAND_MAX. As an example, we'll generate pseudorandom numbers from the range of 0 to 100. Let's generate random numbers with a uniform distribution from 0 to 1. #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { float x; int i; /* Set evil seed (initial seed) */ srand( (unsigned)time( NULL ) ); for (i = 0; i < 5; i++) { x = (float) rand()/RAND_MAX; printf("%f\n", x); } return 0; } There are two tricky points to notice in this program. First, to avoid integer arithmetic, I have explicitly casted the returned value of rand into a float. rand() / RAND_MAX is integer arithmetic. The result is always truncated to zero. (float) rand() / RAND_MAX is floating point arithmetic with a result in the range of 0 to 1, inclusive. The second point to notice is that the value 1.0 is included in the possible results. This may, or may not, be desired. Here's how to exclude 1.0 from the results. rand() / (RAND_MAX + 1.0 )is floating point arithmetic with a result in the range of 0 to 1.0, exclusive of 1.0. Here's the second example. Let's generate numbers between 0 and N-1. Usually, an upper limit of N-1 is desired, rather than N. This is natural, as C is zero based. Arrays of size N run from index 0 to N-1. The following program generates numbers from 0 to 99. #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 100 int main() { int i, j; /* Set evil seed (initial seed) */ srand( (unsigned)time( NULL ) ); for (i = 0; i < 5; i++) { j = (int) N * rand() / (RAND_MAX + 1.0); printf("%d\n", j); } return 0; }