Java的随机函数可以为零吗?

时间:2010-06-17 20:53:23

标签: java random

出于好奇,Math.random()能否为零?

例如,如果我有:

while (true){
  if (Math.random() == 0)
    return 1;
}

我真的会得到一个回报吗?还需要考虑舍入误差,因为Math.random()返回一个double。

我问,因为我的CS教授说random()从0到1(包括0和1),我一直认为它是独占的。

10 个答案:

答案 0 :(得分:38)

是的,真的可以。 Math.random()使用种子java.util.Random创建一个全局(System.currentTimeMillis() ^ 0x5DEECE66DL) & ((1L << 48) - 1) - 生成器,并为其调用nextDouble()。如果其种子到达状态107048004364969L(并且它将会java.util.Random具有完整句点),则生成的下一个double将为0.0。 虽然运气不好,但你可能会在周期中出现错误的平价,因为 Random.nextDouble()两次提升状态。运气少得不好,你可能需要在循环结束前生成2 ^ 47个随机数,因为我没有发现任何其他种子给0.0

种子的进展就好像seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); 使用两个连续种子值的26和27个高位生成双精度数和双精度数。在示例中,两个下一个种子值将为0L11L

如果您设法使用System.currentTimeMillis()==107038380838084L创建全局生成器,则代码会立即返回。你可以用以下方法模拟:

java.util.Random k = new java.util.Random(107038380838084L); System.out.println(k.nextDouble()==0);

答案 1 :(得分:21)

根据the documentation,“返回带有正号的双精度值,大于或等于0.0且小于1.0。”这意味着它可以为零。

作为Hank wrote 在上边界处是独占的(永远不会是1),所以也许这就是你的困惑所在: - )。

答案 2 :(得分:10)

它完全有可能永远不会返回零。 Java包含的PRNG是一个48位的LCG,从中只使用了32位。对于double尾数的所有53位为零,您基本上至少需要一次调用next(),其中高32位为零,另一位大多数为他们是。 (如果我没弄错的话,我会说发生器的工作方式不会发生这种情况,但现在已经很晚了,我已经累了,我也不会打赌它。)

由于方法文档明确说明了如何获得随机数,因此Java运行库的其他实现也没有多余的余地来产生不同的结果。 合同可能会说您获得的数字来自[0,1)。但实际上有很多值你永远不会命中(因为你需要来自生成器的两个连续值,它们可以在连续值之间产生线性相关性 - 只有48位状态。你不能生成所有不同的值53位组合 - 至少不是它的完成方式。)。

当然,由于Math.random()自动播种静态Random实例,我们可能还必须考虑种子,可能需要非常具体的测试案例要解决。这可能意味着确切的时间点可能是几十年或几千年。

答案 3 :(得分:9)

它包含零,不包括零,例如[0, 1)0 <= x < 1,具体取决于您偏好的符号。

答案 4 :(得分:5)

理论上,它可以返回零值。

在实践中,您可能需要等待很长时间才能使完全为零。如果随机数发生器实现良好,它至少有56位内部状态(否则返回结果的所有位都不是随机的)。这意味着,如果随机生成的值的分布是平坦的,那么在2 ^ 56中最多只有一次机会获得所有其位为零的值。这大约是10 ^ -19。我不会屏住呼吸。

(其他人正确地观察到,据记载,理论上[并且可能在实践中]它不能返回值1.0)。

答案 5 :(得分:2)

来自java API。

  

返回带有正号的double值,大于或等于0.0且小于1.0

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#random()

是的,它可以。

答案 6 :(得分:1)

Math.random()是documented返回“具有正号的双精度值,大于或等于0.0且小于1.0” 也就是说,包括0.0但不包括1.0

答案 7 :(得分:1)

在兼容的JRE实现中,它也可能永远不会返回0。

答案 8 :(得分:1)

理论上,math.random()可以返回一个零值,但在现实世界中,你几乎可以指望它永远不会发生。

我曾经连续一周运行我的电脑等待一个,它产生了大约10万亿随机数,没有零。

但更直接的是,它实际上是两种方式都是排他性的。

答案 9 :(得分:0)

来自http://java.sun.com/javase/6/docs/api/java/lang/Math.html

random()返回带有正号的double值,大于或等于0.0且小于1.0。

是的,它可以是零,但不是1.换句话说,更喜欢Java文档而不是你的CS教授=)