これは数学の質問のように見えるかもしれませんが、Javascript の疑似乱数ジェネレーターに排他的にリンクされているため、SO に適していると思います。そうでない場合は、自由に別の場所に移動してください。
まず、ES は疑似乱数ジェネレーターで使用されるアルゴリズムを指定していないことを認識してMath.random()
いますが、範囲はおおよそ均一な分布を持つ必要があると指定しています。
15.8.2.14 ランダム ( )
実装依存のアルゴリズムまたは戦略を使用して、0以上 1 未満の正符号を持つ Number 値を返します。この関数は引数を取りません。
ここまでは順調ですね。今、私は最近MDNからのこのデータに出くわしました:
JavaScript の数値は IEEE 754 浮動小数点数であり、最も近い偶数に丸められるため、
Math.random()
それ自体の範囲を除いて、これらの範囲は正確ではなく、境界によっては非常にまれなケースで可能であることに注意してください ( 2^62の 1 のオーダー) を使用して、通常は除外される上限を計算します。
わかった。それは私をいくつかのテストに導きました、結果は(明らかに)ChromeコンソールとFirefoxのFirebugで同じです:
>> 0.99999999999999995
1
>> 0.999999999999999945
1
>> 0.999999999999999944
0.9999999999999999
私の質問をより明確にするために、簡単な実用的な例に入れましょう。
Math.floor(Math.random() * 1)
上記のコードを考慮すると、IEEE 754 浮動小数点数は最も近い偶数に丸められる動作をし、Math.random()
範囲が均等に分散されているという評価の下で、通常は除外される上限 (1
上記のコード)を返す確率は次のようになると結論付けました。である0.000000000000000055555...
、それはおよそ1/18,000,000,000,000,000
。
MDN 番号を今見ると、 と1/2^62
評価され1/4,611,686,018,427,387,904
ます。つまり、私の計算結果よりも 200 倍以上小さくなっています。
私は間違った計算をしていますか?Firefox の疑似乱数ジェネレーターは、この 200 倍の差を生成するのに十分に均等に分散されていないのでしょうか?
私はこれを回避する方法を知っており、毎日の使用でそのような小さなオッズを考慮する必要さえないことを認識していますが、ここで何が起こっているのか、私の数学が壊れているのか、Mozilla のものなのかを理解したいと思っています (うまくいけば前者です)。=]
どんな入力でも大歓迎です。