JavaScript で乱数をいじっていたときに、おそらく Google Chrome の V8 JavaScript エンジンで、驚くべきバグを発見しました。検討:
// Generate a random number [1,5].
var rand5 = function() {
return parseInt(Math.random() * 5) + 1;
};
// Return a sample distribution over MAX times.
var testRand5 = function(dist, max) {
if (!dist) { dist = {}; }
if (!max) { max = 5000000; }
for (var i=0; i<max; i++) {
var r = rand5();
dist[r] = (dist[r] || 0) + 1;
}
return dist;
};
実行するtestRand5()
と、次の結果が得られます (もちろん、実行ごとにわずかに異なるため、バグを明らかにするために "max" をより高い値に設定する必要がある場合があります)。
var d = testRand5();
d = {
1: 1002797,
2: 998803,
3: 999541,
4: 1000851,
5: 998007,
10: 1 // XXX: Math.random() returned 4.5?!
}
興味深いことに、node.js にも同様の結果が見られ、これは Chrome に固有のものではないと思われます。異なる、または複数のミステリー値 (7、9 など) がある場合があります。
私が見ている結果が得られる理由を誰か説明できますか? parseInt
(の代わりに)を使用することに関係があると思いますが、Math.floor()
なぜそれが起こるのかまだわかりません。