Saturday, 7 September 2013

Using bitwise & instead of modulus operator to randomly sample integers from a range

Using bitwise & instead of modulus operator to randomly sample integers
from a range

I need to randomly sample from a uniform distribution of integers over the
the interval [LB,UB] in C++. To do so, I start with a "good" RN generator
(from Numerical Recipes 3rd ed.) that uniformly randomly samples 64-bit
integers; let's call it int64().
Using the mod operator, I can sample from the integers in [LB,UB] by:
LB+int64()%(UB-LB+1);
The only issue with using the mod operator is the slowness of the integer
division. So, I then tried the method suggested here, which is:
LB + (int64()&(UB-LB))
The bitwise & method is about 3 times as fast. This is huge for me,
because one of my simulations in C++ needs to randomly sample about 20
million integers.
But there's 1 big problem. When I analyze the integers sampled using the
bitwise & method, they don't appear uniformly distributed over the
interval [LB,UB]. The integers are indeed sampled from [LB,UB], but only
from the even integers in that range. For example, here is a histogram of
5000 integers sampled from [20,50] using the bitwise & method:
By comparison, here is what a similar histogram looks like when using the
mod operator method, which of course works fine:
What's wrong with my bitwise & method? Is there any way to modify it so
that both even and odd numbers are sampled over the defined interval?

No comments:

Post a Comment