2017-12-15 13 views
5

私はrandomIO::IO Floatが均一に配信されたことを理解しますFloat番号が、私の質問はどの範囲ですか?それは[0,1](0,1)またはその間にあるもの([0,1)または(0,1])ですか?randomIO(System.Randomから)は0を生成しますか?

hackageには何も見つかりませんでした。参照されている論文は有料ウォールの後ろにあります。

私が尋ねるのは、乱数を変換したい場合があるからです。1/myRandomNumberを評価する場合は、Infinityになるかどうかを知ることが役立つでしょう。

import System.Random 
main=(randomIO::IO Float)>>=print 

Try it online!

答えて

9

短い答え:範囲は[0、1)あります。

はい。 FloatためRandomの実装は[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) 

それはランダム32ビット整数x(ゼロが可能な値である)最初の8ビットのうち、そのマスクを使用し、2によってその値を除算します。その結果、範囲は0(インクルード)〜1(除外)になります。それが表すことができる最大値は0.999999940395です。

このように動作する理由は、Floatに24ビットのmantisse(7ビットの指数と符号ビット)があるためです。その範囲で変換することで、Floatの値が等しくなることが保証されます:最後の24ビットが最初にFloatのmantisseにコピーされ、floatが正規化され、指数が変更されて[0 、1)範囲。

+1

詳細な回答ありがとうございます、私はあなたがソースにアクセスできるかどうかも知りませんでした! – flawr

関連する問題