I understand that randomIO::IO Float produces uniformly distributed Float numbers, but my question is in what range? Is it [0,1], (0,1) or anything in between ([0,1) or (0,1])?
I couldn't find anything about it on hackage, and the referenced paper is behind a paywall.
The reason I'm asking is because you might want to transform the random number, and if you want to evaluate 1/myRandomNumber it would be helpful to know whether you will ever run into Infinity or not.
import System.Random
main=(randomIO::IO Float)>>=print
Try it online!
Short answer: the range is [0, 1).
Yes. The implementation of Random for a Float is [source]:
instance Random Float where
randomR = randomRFloating
random rng =
-- TODO: Faster to just use 'next' IF it generates enough bits of randomness.
case random rng of
(x,rng') ->
-- We use 24 bits of randomness corresponding to the 24 bit significand:
((fromIntegral (mask24 .&. (x::Int32)) :: Float)
/ fromIntegral twoto24, rng')
-- Note, encodeFloat is another option, but I'm not seeing slightly
-- worse performance with the following [2011.06.25]:
-- (encodeFloat rand (-24), rng')
where
mask24 = twoto24 - 1
twoto24 = (2::Int32) ^ (24::Int32)
It uses a random 32-bit integer x (where zero is a possible value), it masks out the first 8 bits, and divides that value by 224. As a result the range is 0 (included) to 1 (excluded). The largest value it can represent is 0.999999940395.
The reason it works that way is because a Float has a 24-bit mantisse (as well as 7-bit exponent and a sign bit). By transforming it in that range, we guarantee that every Float value is equally probable: the last 24 bits are first copied into the mantisse of the Float, then the float is normalized, and the exponent altered such that the values are in the [0, 1) range.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With