Strange behaviour with rand()

2019-09-21 10:42发布

问题:

Why condition rand() % 3 is true approximatelу EVERY 3 time ? rand is REALY random isn't it ?

回答1:

You realize, of course, that even a fair coin can give you ten heads in a row. There's a probability that can be assigned to that combination.

A fair coin will give half heads and half tails over many trials, but it's not guaranteed to be 50/50 over a shorter run.

Your own experience of the physical world tells you that your conclusion is incorrect. Same is true for rand().



回答2:

As the Linux manpage for rand() says:

However, on older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits. Do not use this function in applications intended to be portable when good randomness is needed.

So you might want to either use a different random number generator, or pull higher order bits (which may exhibit more randomness).

A typical implementation of rand() is a linear congruential generator, which is nothing more than a multiply and add of some numbers with special properties (relative primeness). For example, a couple implementations:

  • MSVC 2010 rand():

     return( ((ptd->_holdrand = ptd->_holdrand * 214013L
                + 2531011L) >> 16) & 0x7fff );
    
  • rand() from IAR workbench:

     (x) * 1664525L + 1013904223L           
    

You'll note that MSVC 2010's rand() shifts the result to the right, I assume to help with the problem described in the Linux manpage about non-randomness in the lower order bits.

However, if you want to improve the randomness of your results, you might want to look into using a routine based on something like the Mersenne twister for which implementations are readily available on the Internet.



回答3:

I had the same problem with this code:

#include<iostream.h>
#include<stdlib.h>
int main()
{
    srand(NULL);       
    cout << rand() % 10 + 1;
}

After running it 10 times, I got 1 every time. But I changed the seed to like this:

#include<iostream.h>
#include<stdlib.h>
//new include:
#include<time.h>
int main()
{
    srand(time(NULL));       
    cout << rand() % 10 + 1;
}

It is because the RANDOMIZER takes the seed(srand()), which happens to be null in the first one, then runs a given algorithm, which gives the output 1. If base the seed on time, thus making a "random" result. Hope this helps.



标签: c random