Node:Random numbers, Next:, Previous:ELF vs COFF, Up:Miscellany

22.23 How to produce random numbers?

Q: How do I produce random numbers with DJGPP?

Q: I keep getting the same random numbers each time I run my program. How do I get a different series on every run?

Q: How do I get random numbers between 20 and 200?

A: DJGPP has in its library several functions to produce series of pseudo-random43 numbers. One of them, rand, is part of the ANSI C Standard, and is therefore very portable to other environments. Other random-number functions, random and the rand48 family of functions, are available on almost every Unix platform, but are usually unsupported by DOS/Windows compilers. On the other hand, series produced by random and rand48 have better qualities than those produced by rand. In particular, the least-significant bits in the numbers produced by random are much more random than those you get from rand, so if you need, say, a random number between 0 and 4, and portability is not an issue, you will get better results with random () % 5. However, the DJGPP implementation of rand is quite good, so when portability is important, you should use rand.

Both rand and random return a pseudo-random integer in the range [0..RAND_MAX), where RAND_MAX is defined in the stdlib.h header. Within the rand48 family, some functions return integers, either in the range [0..RAND_MAX) or in [-RAND_MAX..RAND_MAX), while others return a double value between 0.0 and 1.0.

By default, every time you restart a program, you get the same series of pseudo-random numbers. This is important in some applications, because it allows to reproduce exactly the results of running a program which used random series, and thus makes debugging easier. But sometimes, e.g. in a game, you will want a different series every time. To achieve that, you need to initialize the random series with a different seed. Every random-generating function has its own seed function provided for this purpose: rand has srand, random has srandom, the rand48 family can be seeded with either srand48 or seed48. You seed the series with a single call to the appropriate seed function, and then proceed by calling rand, random, etc. as usual.

A popular way of getting a different seed every run is to use the current system clock as the seed, like this:

  srand (time (NULL));

If the 1-second granularity of the values returned by time is not enough for you (e.g., if you need to generate more than one series every second), use gettimeofday or uclock, or use the values returned by rand as an argument to srandom (or vice versa).

To produce random integers from the inclusive interval [low..high] (where low and high are two integer numbers), use code like this:

 #include <stdlib.h>

 int random_number =
       low + (double)rand () * (high - low + 1) / RAND_MAX;

This produces a more random sequence than if you use the % operator, but for the price of producing slower code (since it involves floating-point math).

If you want to know more about random number generation, I suggest reading the article Random Number Generators: Good Ones Are Hard To Find, by Stephen K. Park and Keith W. Miller, in CACM, v31(10), 1988, pp. 1192-1201.