2015-07-20 6 views
1

Я не хочу использовать System.Random, потому что он значительно медленнее, и мне нужно генерировать миллионы случайных поплавков. Я также не могу использовать System.Random.MWC, потому что он не является чистым.Использование System.Random.Mersenne.Pure64 для генерации случайного Float в диапазоне [0,1]

Я сделал попытку написания этого сам, но мое решение не создает однородный диапазон, все значения очень близки к 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 

Я уверен, что функция maxRealFloat правильно потому, что он возвращает correct values for Floats and Doubles according to Wikipedia

ответ

3

Я понял, что делаю очень глупую ошибку. Функция randomDouble в System.Random.Mersenne.Pure64 возвращает double уже в диапазоне [0,1] (который documentation does not mention at all), и все мои номера были очень маленькими, потому что я разделил их на max double.