Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does randomIO (from System.Random) ever produce 0?

Tags:

random

haskell

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!

like image 461
flawr Avatar asked Dec 15 '17 10:12

flawr


1 Answers

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.

like image 107
Willem Van Onsem Avatar answered Oct 18 '22 22:10

Willem Van Onsem