What
Returning rand() % N
does not uniformly give a number in the range [0, N)
, unless N
divides the length of the interval into which rand()
returns (i.e. is a power of 2).
How to do it correctly
unsigned int rand_interval(unsigned int min, unsigned int max)
{
int r;
const unsigned int range = 1 + max - min;
const unsigned int buckets = RAND_MAX / range;
const unsigned int limit = buckets * range;
/* Create equal size buckets all in a row, then fire randomly towards
* the buckets until you land in one of them. All buckets are equally
* likely. If you land off the end of the line of buckets, try again. */
do
{
r = rand();
} while (r >= limit);
return min + (r / buckets);
}
Why
To change the range of rand()
is to divide it into boxes; for example, if RAND_MAX == 11
and you want a range of 1..6
, you should assign {0,1}
to 1, {2,3}
to 2, and so on. These are disjoint, equally-sized intervals and thus are uniformly and independently distributed.