# RNG float range for metropolis monte carlo

I have a robust RNG that generates random 32-bit (unsigned) ints. As is probably well known, for metropolis MC simulation, a random number between 0 and 1 is needed to determine acceptance/rejection of a move, so I need to convert my 32-bit int into a (double-precision) floating point value.

My question is what is best practice for converting my 32-bit int into a float? I think I have the following two options:

• (double) getRandomNumber() / 4294967295 (2^32 - 1); range [0,1]
• (double) getRandomNumber() / 4294967296 (2^32); range [0,1)

The first option seems straightforward, with a range of [0,1]. There would be 2147483648 values in the range [0,0.5) and 2147483648 values in the range (0.5, 1].

In the second option, we have a range of [0,1), and 0.5 is represented exactly among the 2^32 possible floats. There is symmetry in that 50% of the values are in the range [0, .49999999977], and the other 50% are in the range [0.5, .99999999977].

Are there details in the int->double conversion that I am missing? What's standard practice for a range for probabilistic simulations of this type? Is it [0,1], (0,1], [0,1), or (0,1)? Or am I splitting hairs over a trivial matter?

Note I've read that division is less efficient than multiplication, so I do intend to precompute the reciprocal and multiply by that value instead in my actual implementation.

• The standard is to return a value in the range $[0,1)$: see c++'s en.cppreference.com/w/cpp/numeric/random/…. Also: compare the error from this "bias" with the Monte Carlo method's sampling error–assuming $\Theta(n^{-1/2})$ convergence, an error of $2^{-32}$ would only be detectable if you had on the order of $2^{64}$ samples. I'd also add that replacing divisions with multiplications by hand is a typical example of premature optimization–it is nowhere near expensive enough in typical code to worry about it. Jul 26, 2016 at 20:35
• Thanks for the insight. Given the insignificance of the "bias," I will divide by 2^32 -1. Mainly because I must implement a getMaxRN() function which returns int, and I realized that 2^32 can't be represented by an int. Jul 26, 2016 at 22:36
• I just want to note that std::uniform_int_distribution returns a closed range, whereas std::uniform_real_distribution returns the half open range. Jul 28, 2016 at 21:05