Random.nextDouble()可以返回包含值吗?

时间:2016-10-26 03:27:37

标签: java random

我正在使用Random class's nextDouble()方法,如下所示。我希望nextDouble()在区间[-50.0,50.0]上返回伪随机double值,但是,在运行循环10亿次后输出到maximum: 49.99999995014588 minimum: -49.99999991024878。我在没有输出输出间隔操作的情况下运行循环,我得到了maximum: 0.9999999998979311 minimum: 0.0。我发现这很奇怪,因为我对返回的0.0所做的只是乘以100.0并从中减去50.0。为什么下面的代码片段永远不会返回-50.0?

编辑:为了好玩,我又循环了5亿次,输出现在是:maximum: 49.99999994222232 minimum: -49.999999996750944

import java.util.Random;

public class randomTest{

public static void main(String[] args) {

    double max = 0;
    double min = 0;
    Random math = new Random();
    for(int a = 0; a < 1000000000; a++) {
        double rand = math.nextDouble() * 100.0 - (100.0 / 2.0);
        max = Math.max(max, rand);
        min = Math.min(min, rand);
    }
    System.out.println("maximum: " + max + " minimum: " + min);
}
}

5 个答案:

答案 0 :(得分:6)

javadoc明确指出nextDouble()的上限是独占不包括在内。这意味着不会返回1.0

根据javadoc,0.0将被返回....概率大约为1 in 2 54 。 (这是18,014,398,509,481,984中的一次。)

(归结为确定对next(27)的两次连续调用是否会返回零。如果你检查next(int)使用的LCNG的规范,这是可能的。)

因此,您的代码无法点击50.0,因为它无法实现。它应该能够命中-50.0,但你可能需要以1.0E19的顺序运行它才能发生这种情况。你只跑了5.0E8次。

答案 1 :(得分:3)

If objLogical.Exist(0) Then strLogicalName = objLogical.GetROProperty("title") Reporter.ReportEvent micPass,"Check existance of [" & strLogicalName & "]","[" & strLogicalName & "] exists." Else Reporter.ReportEvent micFail,"Check existance of [" & objLogical.ToString()& "]","[" & objLogical.ToString()& "] not exists." End If 首先生成一个随机nextDouble(),即在数字-2 63 和2 63 -1之间均匀分布的整数。如果你产生10亿个数字,你仍然只能生成10个 9 / 2 64 = 5.421 x 10 -11 的可能性分数。因此,产生任何特定数字的几率非常小。

即使考虑到四舍五入,机会仍然很小。请注意,您的输出包含16位有效数字,这意味着您可以生成10 15 和10 16 之间的可能十进制数字序列。如果你只产生10个 9 ,那么产生任何特定数字的概率是10 -7

答案 2 :(得分:3)

取自oracle docs:

  

public double nextDouble()统一返回下一个伪随机数   从该随机数分布的值介于0.0和1.0之间   发电机的顺序。 nextDouble的总合同就是那个   双值,从 0.0d范围内均匀选择(近似)   (包括)到 1.0d(不包括,是伪随机生成的   返回。

     

方法nextDouble由Random类实现,如下所示:

public double nextDouble() {    return (((long)next(26) << 27) +
> next(27))
>      / (double)(1L << 53);  }

对冲&#34;大约&#34;在前面的描述中使用的仅仅是因为下一个方法仅是

  

大约是一个独立选择位的无偏源。如果它   是随机选择的比特的完美来源,然后是算法   显示将从所述范围中选择具有完美的双值   均匀性。

     

[在Java的早期版本中,结果错误地计算为:

return (((long)next(27) << 27) + next(27))
>      / (double)(1L << 54);

这似乎是等效的,如果不是更好,但实际上由于

它引入了很大的不均匀性
  浮点数的四舍五入偏差:它是三倍   可能是有效数字的低位比0更低   它会是1!这种不均匀性可能并不重要   练习,但我们力求完美。]

因此很明显,生成数字时不包括最大值

答案 3 :(得分:1)

自己实施。对我有用的东西:

public double nextDoubleInclusive()
{
    return myRandom.nextInt(Integer.MAX_VALUE) / (Integer.MAX_VALUE - 1.0);
}

答案 4 :(得分:0)

注意在没有偏移的情况下运行时你可能没有得到0.0。 你的“min”以0.0开头。

对你的代码进行一点改动(min = 1)你可以看到你没有得到0.0(你可能,而不是你的赔率)。

    double max = 0;
    double min = 1;
    Random math = new Random();
    for(int a = 0; a < 1000000000; a++) {
        double rand = math.nextDouble();
        max = Math.max(max, rand);
        min = Math.min(min, rand);
    }
    System.out.println("maximum: " + max + " minimum: " + min);

最大值:0.9999999989149039最小值:4.5566594941703897E-10

相关问题