この質問:ランダムなBigIntegerを生成する方法は、BigIntegerのRandom.nextInt(int n)と同じセマンティクスを実現する方法を説明しています。
BigDecimalとRandom.nextDouble()についても同じことをしたいと思います。
上記の質問の1つの答えは、ランダムなBigIntegerを作成し、それからランダムなスケールでBigDoubleを作成することを提案しています。非常に簡単な実験は、これが非常に悪い考えであることを示しています:)
私の直感では、このメソッドを使用するには、整数をのようなものでスケーリングする必要がありますn-log10(R)
。ここで、nは出力に必要な精度の桁数であり、RはランダムなBigIntegerです。これにより、(たとえば)1-> 10^-64および10^64-> 1となるように、正しい桁数が存在するようになります。
結果が[0,1]の範囲に収まるようにするには、スケーリング値も正しく選択する必要があります。
誰かが以前にこれを行ったことがあり、結果が正しく配布されているかどうかを知っていますか?これを達成するためのより良い方法はありますか?
編集:スケール引数の私の理解を修正してくれた@biziclopに感謝します。上記は必須ではありません。一定の倍率で目的の効果が得られます。
後で参照するために、私の(明らかに機能しているコード)は次のとおりです。
private static BigDecimal newRandomBigDecimal(Random r, int precision) {
BigInteger n = BigInteger.TEN.pow(precision);
return new BigDecimal(newRandomBigInteger(n, r), precision);
}
private static BigInteger newRandomBigInteger(BigInteger n, Random rnd) {
BigInteger r;
do {
r = new BigInteger(n.bitLength(), rnd);
} while (r.compareTo(n) >= 0);
return r;
}