s
1からまでの整数の合計がでn
あると考えてくださいs = n * (n + 1) / 2
。を取得するために解決n
しますn = (± sqrt(8*s + 1) - 1) / 2
。正であることがわかっているので、負の平方根は無視できn
ます。したがってn = (sqrt(8*s + 1) - 1) / 2
。
したがって、1〜15の整数をプラグインしますs
。
s n
01 1.000000
02 1.561553
03 2.000000
04 2.372281
05 2.701562
06 3.000000
07 3.274917
08 3.531129
09 3.772002
10 4.000000
11 4.216991
12 4.424429
13 4.623475
14 4.815073
15 5.000000
計算されたそれぞれの上限n
(以上の最小の整数n
)を取ると、次のようになります。
s n
01 1
02 2
03 2
04 3
05 3
06 3
07 4
08 4
09 4
10 4
11 5
12 5
13 5
14 5
15 5
したがって、一様分布から一定の空間と一定の時間での分布に移行できます(反復や事前計算されたテーブルはありません)。
double my_distribution_from_uniform_distribution(double s) {
return ceil((sqrt(8*s + 1) - 1) / 2);
}
注意:これは、完全な正方形に対して正確な結果を与えることに依存していますsqrt
(たとえば、正確に49を指定すると正確に7を返します)。IEEE 754では平方根を正確に丸める必要があるため、これは通常、安全な仮定です。
IEEE 754 doubleは、1から2 ^ 53までのすべての整数を表すことができます(さらに多くの大きな整数ですが、2 ^ 53以降は連続していません)。s
したがって、この関数は1からまでのすべてで正しく機能するはずfloor((2^53 - 1) / 8) = 1125899906842623
です。