unsigned const number = minimum + (rand() % (maximum - minimum + 1))
I know how to (easily) generate a random number within a range such as from 0 to 100. But what about a random number from the full range of int
(assume sizeof(int) == 4
), that is from INT_MIN
to INT_MAX
, both inclusive?
I don't need this for cryptography or the like, but a approximately uniform distribution would be nice, and I need a lot of those numbers.
The approach I'm currently using is to generate 4 random numbers in the range from 0 to 255 (inclusive) and do some messy casting and bit manipulations. I wonder whether there's a better way.
We should be able to do something that works no matter what the range of
rand()
or what size result we're looking for just by accumulating enough bits to fill a given type:Note: Makes the minimum number of calls to
rand()
necessary to populate all bits.Let's verify this gives a uniform distribution.
At this point we could just cast the result of
rand_uint()
to type int and be done, but it's more useful to get output in a specified range. The problem is: How do we reachINT_MAX
when the operands are of type int?Well... We can't. We'll need to use a type with greater range:
As a final note, it may be worthwhile to implement the random function in terms of type double instead, i.e., accumulate enough bits for
DBL_MANT_DIG
and return a result in the range [0,1). In fact this is whatstd::generate_canonical
does.On my system
RAND_MAX
is 32767 which is 15 bits. So for a 32-bitunsigned
just call three times and shift, or, mask etc.Program output:
For reference I'm adding what I've been using:
But I like Weather Vane's solution better because it uses fewer
rand()
calls and thus makes more use of the (hopefully good) distribution generated by it.