Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First random number is always smaller than rest

Tags:

c++

random

qt

I happen to notice that in C++ the first random number being called with the std rand() method is most of the time significant smaller than the second one. Concerning the Qt implementation the first one is nearly always several magnitudes smaller.

qsrand(QTime::currentTime().msec()); qDebug() << "qt1: " << qrand(); qDebug() << "qt2: " << qrand();  srand((unsigned int) time(0)); std::cout << "std1: " << rand() << std::endl; std::cout << "std2: " << rand() << std::endl; 

output:

qt1:  7109361 qt2:  1375429742 std1: 871649082 std2: 1820164987 

Is this intended, due to error in seeding or a bug? Also while the qrand() output varies strongly the first rand() output seems to change linearly with time. Just wonder why.

like image 462
Sharky Bamboozle Avatar asked May 25 '15 01:05

Sharky Bamboozle


People also ask

Is Rand completely random?

RAND returns an evenly distributed random real number greater than or equal to 0 and less than 1. A new random real number is returned every time the worksheet is calculated. Note: As of Excel 2010, Excel uses the Mersenne Twister algorithm (MT19937) to generate random numbers.

Does Rand include 0 in C?

C library function - rand()The C library function int rand(void) returns a pseudo-random number in the range of 0 to RAND_MAX. RAND_MAX is a constant whose default value may vary between implementations but it is granted to be at least 32767.

Does rand () include 0 C++?

Conclusion. rand() function in c++ is used to generate random numbers in a code. rand function in c++ returns any integer ranging from (o to rand_max), as defined by the user. this function is defined in the header file "cstdlib" in C++.

What is random number functions?

Random number generation is a process by which, often by means of a random number generator (RNG), a sequence of numbers or symbols that cannot be reasonably predicted better than by random chance is generated.


1 Answers

I'm not sure that could be classified as a bug, but it has an explanation. Let's examine the situation:

  1. Look at rand's implementation. You'll see it's just a calculation using the last generated value.

  2. You're seeding using QTime::currentTime().msec(), which is by nature bounded by the small range of values 0..999, but qsrand accepts an uint variable, on the range 0..4294967295.

By combining those two factors, you have a pattern.

Just out of curiosity: try seeding with QTime::currentTime().msec() + 100000000

Now the first value will probably be bigger than the second most of the time.

I wouldn't worry too much. This "pattern" seems to happen only on the first two generated values. After that, everything seems to go back to normal.

EDIT:

To make things more clear, try running the code below. It'll compare the first two generated values to see which one is smaller, using all possible millisecond values (range: 0..999) as the seed:

int totalCalls, leftIsSmaller = 0; for (totalCalls = 0; totalCalls < 1000; totalCalls++) {     qsrand(totalCalls);     if (qrand() < qrand())         leftIsSmaller++; } qDebug() << (100.0 * leftIsSmaller) / totalCalls; 

It will print 94.8, which means 94.8% of the time the first value will be smaller than the second.

Conclusion: when using the current millisecond to seed, you'll see that pattern for the first two values. I did some tests here and the pattern seems to disappear after the second value is generated. My advice: find a "good" value to call qsrand (which should obviously be called only once, at the beginning of your program). A good value should span the whole range of the uint class. Take a look at this other question for some ideas:

  • Recommended way to initialize srand?

Also, take a look at this:

  • PCG: A Family of Better Random Number Generators
like image 56
Rafael Monteiro Avatar answered Sep 23 '22 04:09

Rafael Monteiro