First random number is always smaller than rest

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

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)