这个问题:How to generate a random BigInteger描述了一种实现与 BigIntegers 的 Random.nextInt(int n) 相同语义的方法。
我想对 BigDecimal 和 Random.nextDouble() 做同样的事情。
上述问题中的一个答案建议创建一个随机的 BigInteger,然后从中创建一个具有随机比例的 BigDouble。一个非常快速的实验表明这是一个非常糟糕的主意:)
我的直觉是,使用这种方法需要将整数缩放为n-log10(R)
,其中 n 是输出中所需的精度位数,R 是随机 BigInteger。这应该允许出现正确的位数,以便(例如)1 -> 10^-64 和 10^64 -> 1。
还需要正确选择缩放值,以使结果落在 [0,1] 范围内。
有没有人这样做过,他们知道结果是否正确分布?有没有更好的方法来实现这一目标?
编辑:感谢@biziclop 纠正了我对 scale 参数的理解。以上不是必需的,恒定的比例因子具有预期的效果。
供以后参考,我的(显然是工作代码)是:
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;
}