In the FAQ I read:
If you just need to do something with probability 1/N, you could use
if(rand() < (RAND_MAX+1u) / N)
This has an obvious bias problem which is easily fixed (not
perfectly, but an improvement).
There are RAND_MAX + 1 values RAND_MAX can return. So we want to
pick (RAND_MAX + 1.0) / N of them. This is probably not an
integer. So we might want to round it to nearest integer. If we
are willing to use floating point, it turns out that if x is a
positive real number, there are ceil(x) non-negative integers such
as n < x. (For example, if x is 3 there are 3 such values: 0, 1,
and 2. If x is 3.2 there are 4 such values: 0, 1, 2 and 3.) Now
the nearest integer to x is ceil(x - 0.5). [1] So we might try to
do
if (rand() < (RAND_MAX + 1.0) / N - 0.5)
or, for an arbitrary fraction p, not necessarily 1 / N:
if (rand() < p * (RAND_MAX + 1.0) - 0.5)
Now, if we don't want to use floating point, getting back to the
case 1 / N, we can use
if (rand() < (RAND_MAX + 1u + N / 2) / N)
[1] The problem is when p * (RAND_MAX + 1.0) is exactly half an
odd integer. When p is 1 / N this isn't a great concern, because,
where RAND_MAX + 1.0 is a power of two, this is impossible, unless
N is 2 * RAND_MAX, which can be handled in a more obvious way as
if (rand() == 0 && rand() RAND_MAX / 2).
--
Army1987 (Replace "NOSPAM" with "email")
"Never attribute to malice that which can be adequately explained
by stupidity." -- R. J. Hanlon (?)