Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm having a strange problem here, and I can't manage to find a good explanation to it, so I thought of asking you guys :

Consider the following method :

int MathUtility::randomize(int Min, int Max)
    qsrand(QTime::currentTime().msec());
    if (Min > Max)
        int Temp = Min;
        Min = Max;
        Max = Temp;
    return ((rand()%(Max-Min+1))+Min);

I won't explain you gurus what this method actually does, I'll instead explain my problem :

I realised that when I call this method in a loop, sometimes, I get the same random number over and over again... For example, this snippet...

for(int i=0; i<10; ++i)
    int Index = MathUtility::randomize(0, 1000);
    qDebug() << Index;

...will produce something like :

567...etc...

I realised too, that if I don't call qsrand everytime, but only once during my application's lifetime, it's working perfectly...

My question : Why ?

Because if you call randomize more than once in a millisecond (which is rather likely at current CPU clock speeds), you are seeding the RNG with the same value. This is guaranteed to produce the same output from the RNG.

Random-number generators are only meant to be seeded once. Seeding them multiple times does not make the output extra random, and in fact (as you found) may make it much less random.

Thanks, man. Two-line example for syntax-sake: 1: qsrand(QTime::currentTime().msec()); 2: int number = rand() % (100-0+1)+0; Just swap 100 with your max number and 0 with your minimum number. – kayleeFrye_onDeck Jan 20, 2017 at 1:31

If you call the qsrand Qt function to initialize the seed, you must call the qrand Qt function to generate a random number, not the rand function from the standard library. the seed initialization for the rand function is srand. Sorry for the dig up.

What you see is the effect of pseudo-randomness. You seed it with the time once, and it generates a sequence of numbers. Since you are pulling a series of random numbers very quickly after each other, you are re-seeding the randomizer with the same number until the next millisecond. And while a millisecond seems like a short time, consider the amount of calculations you're doing in that time.

int getRand(int min, int max){ unsigned int ms = static_cast<unsigned>(QDateTime::currentMSecsSinceEpoch()); std::mt19937 gen(ms); std::uniform_int_distribution<> uid(min, max); return uid(gen);

1 As others have pointed out, the generator is being seed multiple times.

2 This is not a very good method to generate random numbers within a given range. (In fact it's very very bad for most generators )

You are assuming that the low-order bits from the generator are uniformly distributed . This is not the case with most generators. In most generators the randomness occurs in the high order bits.

By using the remainder after divisions you are in effect throwing out the randomness.

You should scale using multiplication and division. Not using the modulo operator.

my_number= start_required + ( generator_output * range_required)/generator_maximum;

if generator_output is in [0, generator_maximum] my_number will be in [start_required , start_required + range_required]

I've found the same action and solved it by using rand() instead the srand().

But I use it for checking my application. It just working in the cicle, so I don't need to look for it updates.

But if you going to do some king of game, it isn't a good way, because your randomizing will be the same.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.