実際、私はいくつかの織り交ぜる質問があります。(重要な場合はC#を使用します。)
初め。0からUInt32.MaxまでのUInt32範囲の乱数を生成するprngがあります。できるだけ均一性を保ちたいです。[a、b]、(a、b)の二重範囲([0,1]、[0,1)、(0,1)、[-2,4]、(-など)を取得するための主なアイデアは何ですか10,10))?
次のことが気になります。4 294 967296prngの結果があります。[0,1] double範囲の数値よりも小さい— 2^53。そこで、2桁から4 294 967 296-ary番号を作成します。これは、[0、4294967295 * 4294967296+4294967295]でランダムで均一です。この最大値は1の2^53より大きいため、1つ取得した場合は破棄し、再計算してmod 2 ^ 53を使用し、たとえば[0,1]で背番号を取得します。ここでは、最大値をdoubleとして表す必要があります(Int64タイプがないと仮定します)—これには欠点がありますか?
ここで、[0,1)を取得したい場合、結果の数は(2 ^ 53)-1であると考えます。最後の結果に1 /(2 ^ 53)を追加すると、(0,1]にランダムなdoubleが生成されます。 。(0,1)を取得するには、(2 ^ 53)-2つの新しい結果を検討し、0ベースの結果に1 /(2 ^ 53)を追加します。それはすべて正しいですか。
しかし、ダブルレンジ全体に近いか等しいダブルレンジを取得するにはどうすればよいですか?上記のようにn-ary数を作成しても、Double.Maxより大きくなる場合があります。いくつかのビットシフト/ビットマスクアプローチが可能でしょうか?
2番。これで、結果が[0,1)のdouble prngがあり、[Double.Min、Double.Max]の範囲を取得することは可能ですか?ダブルナンバーはいくつありますか?フルダブルレンジprngがある場合、UIntレンジを取得するための最良の方法は何ですか?「直接」マップするか、前に[0,1]にスケーリングしますか?
第3。このコードを見つけました(http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c):
/* generates a random number on [0,1) with 53-bit resolution*/
double genrand_res53(void)
{
unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
return(a*67108864.0+b)*(1.0/9007199254740992.0);
}
なぜaとbが5と6にシフトし、その後a * 67108864.0 + bが均一になるのですか?
ありがとうございました。