| 2007/08/31(Fri) 21:10:56 編集(投稿者)
■No7208 (魔界の仮面弁士 さん) に返信 > ■No7197 (れい さん) に返信 > System.Random.Next だと、 > .Next(1, 1) > .Next(1, 2) > が、いずれも「固定値 1」になる仕様なんですよね。 > 私は、これはこれで違和感を感じていたりします。
あ。ほんとだ。これは…ひどい。
ごにょっていたら、昔書いた、Randomクラスの問題点を調べた資料を見つけました。 あまりに細かい問題なので、まだWebで見たことはありません。 便乗してここに書いておきます。
(1) Random.Nextは0〜0x7FFFFFFEの値を返す。 (2^31-1)通りであり、intの最大値である0x7FFFFFFFは返さない。 これはドキュメントに書いてある通り。
(2) Random.NextDoubleは0〜0.999999999534339の範囲で4.6566128752457969E-10置きの値しか返さない。 Random.NextDoubleは(Random.Next*4.6566128752457969E-10)と同値。 例えば、Doubleの1未満の最大値である BitConverter.ToDouble(New Byte() {&HFF, &HFF, &HFF, &HFF, &HFF, &HFF, &HEF, &H3F} は返さない。
(3) Next(int maxvalue)はRandom.NextDouble*maxvalueと同値。 丸め誤差のせいで、確率分布がおかしい。
(4) Next(int minvalue, int maxvalue)はmaxvalue-minvalueが&H7fffffffより大きいか、小さいかで確率がだいぶ変わる。 小さい場合はNext(int maxvalue)と同じ問題が生じる。 大きい場合はさらに、minとmaxの中間値が出る確率が2倍になる問題が生じる。
(5) Random.NextByteは、&HFFが微妙に少ない。 Random.Nextの下位8bitを取っていることからくる問題。 具体的には 0x7FFFFF/0x800000 = 0.99999988079071044921875 だけ少ない。
RandomはNumerical RecipesのKnuthのコードそのままらしいのですが、 実装にいろいろ問題が在ります。 普通気にならないレベルなのかもしれませんが、 Randomを大規模に使うなら自分で実装したほうがいいですね。 |