Qt random number

The random number generation functions are always confusing. We often use the C rand() function to generate an integer number between 0 and RAND_MAX. We call it several times and every time it generates a different integer so the generated numbers seem random – that is why rand is called pseudo-random generator. But wait a minute, when you restart your program, then call rand() several times, you will find the number sequence is the same as the one in last run. That is not good because if every run of the program produces the same integer sequence, it is not random at all and rand should not be called a random number generator.  We want rand not only generates a random number sequence in a run of program, but also generates a different sequence of numbers in different runs of the program. That is what we want, a real random-number generator.

How can we achieve that? We can use srand(seed) to  generate a different seed for the generation of numbers by rand. For example, we can call srand(3) when program begins to rum. Then later callings of the rand function will generate random numbers based on the seed 3. The random number generation process of rand is: generate the first number from the seed 3, generate the second number from the first number, generate the third number from the second number, etc. Thus, a different seed will bring a total different sequence of succeeding numbers.

How do we guarantee the program picks a different seed at each run? We can use the time() function. This function returns the seconds elapsed since 00:00:00 UTC, January 1, 1970. Since every run of the program occurs at different time, the time function will return different values for seed:

srand(time(0)).

You may wonder why time takes a 0 as its parameter. Well, it is not the start point of time to calculate the time distance. The time interval is always calculated by current time relative to 00:00:00 UTC, January 1, 1970. The parameter of the time function is actually a NULL pointer. The pointer, if not NULL,  is used to store the returned value. But the pointer can also be null which means we do not need to store the interval, we just use the returned value of time().

The cooperation of srand and rand can make it possible to generate a real randomly-looking number sequence. But it is still called pseudo-random number because the whole number generation process is deterministic including the seed. In fact, it is a hard task to find a real random number sequence in nature.   But the pseudo-random number is enough to do most work such as statistics simulation.

If you do not call srand before calling rand, rand will generate the random number sequence from the seed 1. So, it is equivalent to calling srand(1) before calling rand. Of course, repeatedly runnings of your program produce the same sequence.

Qt has its thread-safe version of rand called qrand. Qt also has its thread-safe version of srand called qsrand. The usage of qrand and qsrand is the same as C rand and C srand.

New version of Qt introduces a new random number generator class QRandomGenerator. The simple usage of QRandomGenerator  is:

QRandomGenerator::global()->bounded(lowest,highest);

which generates a number in the range of lowest to highest. The best part is that you do not need to seed at the beginning of your program. Every time the function is called, it generates a different number of type quint32, even across the run of program, i.e., in the first calling at run 2, it generates a different number than the first calling at run 1. Qt team suggests to use this new random number generator and says qrand and qsrand are deprecated.

 

 

 

Posted in

Leave a Reply