Why does this code generates uniformly distributed numbers? I have some difficulties in understanding it. Could someone explain? Thanks.
int RandomUniform(int n) {
int top = ((((RAND_MAX - n) + 1) / n) * n - 1) + n;
int r;
do {
r = rand();
} while (r > top);
return (r % n);
}
update: I do understand why rand()%n doesn’t give you a uniformly distributed sequence. My question is why the
top = ((((RAND_MAX - n) + 1) / n) * n - 1) + n;
What’s the concern here? I think a simple top = RAND_MAX / n * n would do.
The function assumes that
rand()is uniformly distributed; whether or not that is a valid assumption depends on the implementation ofrand().Given a uniform
rand(), we can get a random number in the range[0,n)by calculatingrand()%n. However, in general, this won’t be quite uniform. For example, supposenis 3 andRAND_MAXis 7:We can see that 0 and 1 come up with a probability of 3/8, while 2 only comes up with a probability of 2/8: the distribution is not uniform.
Your code discards any value of
rand()greater or equal to the largest multiple ofnthat it can generate. Now each value has an equal probability:So 0,1 and 2 all come up with a probability of 1/3, as long as we are not so unlucky that the loop never terminates.
Regarding your update:
If
RAND_MAXwere an exclusive bound (one more than the actual maximum), then that would be correct. Since it’s an inclusive bound, we need to add one to get the exclusive bound; and since the following logic compares with>against an inclusive bound, then subtract one again after the calculation:However, if
RAND_MAXwere equal toINT_MAX, then the calculation would overflow; to avoid that, subtractnat the beginning of the calculation, and add it again at the end: