【问题标题】:Obtaining random double with inclusive max value (Java - ThreadLocalRandom)获取具有包含最大值的随机双精度(Java - ThreadLocalRandom)
【发布时间】:2017-07-25 09:04:16
【问题描述】:

我有一种方法可以在最小值和最大值之间获得随机双精度值。我的问题是,如果值是例如 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);
}

这个问题还有其他解决方案吗?

【问题讨论】:

  • 您计算过这成为问题的概率吗?

标签: java random double


【解决方案1】:

最简单的解决方案是忽略这个问题。

仅考虑简单的 [0,1] 情况。我不知道您希望分配给上限的概率,但最大的合理概率是 1.0 和小于 1.0 的最大双精度之间的绝对差。那个差是2-53,大约是1.11e-16,是很小的概率。

在 1e9 试验中未获得 1.0 的概率为 0.9999998889777038。

【讨论】:

    【解决方案2】:

    我想你可以这样做:

    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;
    

    概率仍然不均匀,但 max 实际上具有与 min 之外的所有其他概率相同的概率。 min 的概率稍微大一些(但实际上只是非常小,甚至无法与之前相比)。

    【讨论】:

      【解决方案3】:

      一种方法是使用以下代码:

      Random r = ThreadLocalRandom.current();
      return min + ((double)r.nextLong(9007199254740993L) / 
           9007199254740992.0) * (max - min);
      

      请注意,部分代码生成的 long 小于 9007199254740993 (253+1) 和 将其除以 253,得到一个 0 或更大、1 或更少的数字。还有一个更复杂的方法,以及你的问题的某些微妙之处,我详细描述on another page;但是,这篇文章中给出的方法很可能足以满足您的目的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-07
        • 2012-04-01
        • 2016-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-26
        相关资源
        最近更新 更多