我有一种方法可以获得最小值和最大值之间的随机双精度。我的问题是,如果值是例如0D和10D,我永远不会获得10D作为可能的结果,因为nextDouble第二个参数是独占的。
public static Double randomDouble(Double min, Double max) {
return ThreadLocalRandom.current().nextDouble(min, max);
}
如果我将这一行放在我的方法中,我就获得了10D的结果,但我不知道这是不是一个好习惯。
public static Double randomDouble(Double min, Double max) {
max = max + 0.000000000000001D;
return ThreadLocalRandom.current().nextDouble(min, max);
}
这个问题还有其他解决方案吗?
答案 0 :(得分:2)
最简单的解决方案是忽略这个问题。
只考虑简单的[0,1]案例。我不知道你想要分配到上限的概率,但最大的合理概率是1.0和最大双重之间的绝对差值小于1.0。差异为2 -53 ,约为1.11e-16,这是一个非常小的概率。
在1e9试验中未获得1.0的概率为0.9999998889777038。
答案 1 :(得分:1)
我想你可以这样做:
if (ThreadLocalRandom.current().nextDouble() < 0.5) {
return ThreadLocalRandom.current().nextDouble(min, max);
}
return max - ThreadLocalRandom.current().nextDouble(0, max - min);
但是:虽然这种方法会将最大值增加到可能的结果,但获得精确的最大值或最小值的概率实际上只是其他任何数字可能具有的概率的一半。
这意味着它几乎与:
相同double result = ThreadLocalRandom.current().nextDouble(min, max);
if (result == min && Thread.LocalRandom.current().nextDouble() < 0.5) {
result = max;
}
return result;
稍微好一点的方法可能是
double result = ThreadLocalRandom.current().nextDouble(min, max);
if (result != min) {
result = max - ThreadLocalRandom.current().nextDouble(0, max - min);
}
return result;
概率仍然不均衡,但除了min之外,max实际上具有相同的概率。 min的概率稍微大一点(但实际上只是非常轻微,甚至与之前的情况相当)。
答案 2 :(得分:1)
一种方法是使用以下代码:
Random r = ThreadLocalRandom.current();
return min + ((double)r.nextLong(9007199254740993L) /
9007199254740992.0) * (max - min);
请注意,部分代码生成long
小于9007199254740993(2 53 +1)并且
除以2 53 ,得到数字0或更大,1或更小。还有一种更复杂的方法,以及你的问题的某些微妙之处,我详细描述了on another page;但是,这篇文章中给出的方法很可能足以满足您的目的。