この論文で説明されているWELL512疑似乱数ジェネレータ関数を使用しています。この関数はランダムなunsigned long
値を返します。
この戻り値を使用して、特定の範囲内のランダムな実数を生成するにはどうすればよいですか。たとえば、340.92491から859812.53198までの浮動小数点数です。
C rand()関数のドキュメントは、modの使用に対して警告しているようです。
まあ、数学的にはそれはただです:
min_value + (max_value - min_value) * (my_random() / (long double)ULONG_MAX)
(my_random()が0からULONG_MAXまでの一様分布の数値を返すと仮定します)
ただし、、、、およびの正確な値によってはmin_value
、一部の浮動小数点数が他の数値よりも確実に発生する可能性があります。max_value
ULONG_MAX
考えられる各ランダムな符号なしlongは、この式によってfloatにマップされます。min_value
ただし、との間の個別の浮動小数点数の数max_value
はほぼ確実に正確ではないためULONG_MAX
、一部のunsigned longは同じ浮動小数点数にマップされるか、一部の浮動小数点数にはそれらへのunsignedlongマップがないかまたは両方になります。
結果を真に均一にするためにこれを修正することは...自明ではないと思います。多分誰かが私が論文を引用するよりもよく読んでいます。
[編集]
または、この質問への回答を参照してください。
double
その答えは、IEEE表現の内部に依存します。また、それがどのように機能するかを完全に理解しているかどうかもわかりません。
[編集2]
OK、それがどのように機能するか理解しました。アイデアは、最小値と最大値の間のランダムな浮動小数点表現を選択し、指数で表されるスケールに反比例する確率でそれを破棄することです。一様分布の場合、(たとえば)1/2と1の間の数値は、1から2の間の数値の半分である必要がありますが、これらの範囲の浮動小数点表現の数は同じです。
ffs
最初に対数スケールで指数を選択し(たとえば、ランダムに選択された整数を使用して)、次に仮数をランダムに選択することで、そのコードをより効率的にすることができると思います。うーん...
実数をunsignedlongに変換することは可能ですか?それが簡単にできれば、WELL512は機能すると思います。幸運を。
浮動小数点数を使用して均一に分散された実数を表すことはまったく不可能です。範囲内の実数の数は数え切れないほどありますが、浮動小数点数の数は限られています。
さらに悪いことに、範囲が浮動小数点の指数境界を超える場合、浮動小数点数として表現できる範囲内の有限数の実数が均等に分散されない場合があります。