s1からまでの整数の合計がで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です。