I do not want to use System.Random because it is significantly slower and I need to generate millions of random floats. I also cannot use System.Random.MWC because it is not pure.
I made an attempt at writing this myself but my solution does not generate a uniform range, all the values are very close to 0.
randomRMSP :: (Float,Float) -> PureMT -> (Float,PureMT)
randomRMSP (lo,hi) rng =
let (f,rng') = first double2Float (randomDouble rng)
in (lo + f / (maxFloat + 1) * (hi - lo + 1),rng')
maxRealFloat :: RealFloat a => a -> a
maxRealFloat a = encodeFloat m n where
b = floatRadix a
e = floatDigits a
(_, e') = floatRange a
m = b ^ e - 1
n = e' - e
I'm pretty sure the maxRealFloat function is correct because it returns the correct values for Floats and Doubles according to Wikipedia
I realized I was making a very silly mistake. The function randomDouble in System.Random.Mersenne.Pure64 returns a double already in the range [0,1] (which the documentation does not mention at all) and consquently all my numbers were very small because I was dividing them by the max double.