これはおそらく x86 FPU の専門家に対する質問です。
[最小、最大] の範囲でランダムな浮動小数点値を生成する関数を作成しようとしています。問題は、私の生成アルゴリズム (興味があるなら、浮動小数点 Mersenne Twister) が [1,2) の範囲の値しか返さないことです。つまり、包括的な上限が必要ですが、「ソース」で生成された値は排他的上限から。ここでの問題は、基になるジェネレーターが 8 バイトの double を返すことですが、必要なのは 4 バイトの float だけであり、デフォルトの FPU 丸めモードである Nearest を使用しています。
私が知りたいのは、この場合の切り捨て自体が、FPU 内部の 80 ビット値が十分に近い場合に戻り値が最大値を含む結果になるかどうか、または最大値に乗算する前に最大値の仮数をインクリメントする必要があるかどうかです。 [1,2) の中間ランダム、または FPU モードを変更する必要があるかどうか。もちろん、その他のアイデアも。
現在使用しているコードは次のとおりです。1.0f が 0x3f800000 に解決されることを確認しました。
float MersenneFloat( float min, float max )
{
//genrand returns a double in [1,2)
const float random = (float)genrand_close1_open2();
//return in desired range
return min + ( random - 1.0f ) * (max - min);
}
違いがある場合、これは Win32 MSVC++ と Linux gcc の両方で動作する必要があります。また、SSE 最適化のいずれかのバージョンを使用すると、これに対する答えが変わりますか?
編集:答えはイエスです。この場合、double から float への切り捨ては、結果に max を含めるのに十分です。詳細については、Crashworks の回答を参照してください。