代码之家  ›  专栏  ›  技术社区  ›  ThirdD3gree

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

  •  16
  • ThirdD3gree  · 技术社区  · 14 年前

    只是出于好奇,math.random()可以是零吗?

    例如,如果我有:

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

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

    我这样问是因为我的CS教授说random()从0到1(包含0到1),我一直认为它是排他的。

    10 回复  |  直到 7 年前
        1
  •  21
  •   Community dbr    7 年前

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

    AS Hank wrote 在上边界上是独占的(永远不能是1),所以也许这就是你混淆的来源:—)。

        2
  •  38
  •   Angs    14 年前

    是的,它 真的? 可以是。 Math.random() 创建全局 java.util.Random -带种子的发电机 (System.currentTimeMillis() ^ 0x5DEECE66DL) & ((1L << 48) - 1) 和电话 nextDouble() 为了它。如果种子达到状态 107048004364969L (它会的,因为 java.util.random随机 有完整的句号),下一个 double 将生成 0.0 . 尽管运气不好,你可能会在周期中以错误的平价结束,因为 Random.nextDouble() 使状态前进两次。如果运气不好的话,你可以在循环终止前生成2^47个随机数,因为我没有找到任何其他种子 .

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

    如果您试图用 System.currentTimeMillis()==107038380838084L ,您的代码立即返回。您可以使用以下方法模拟:

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

        3
  •  10
  •   Malady    7 年前

    它很可能永远不会精确地归零。Java包含的PRNG是一个48位LCG,其中只有32位被使用过。所有53位A double 尾数为零,你至少需要 打电话给 next() 其中32位的上限为零,另一位的大部分为零。(如果我没弄错的话,我会说发电机的工作方式永远不会发生这种情况,但是很晚了,我累了,我不会在这上面下太多赌注。)

    由于方法文档明确地说明了如何获得随机数,因此对于Java运行时的其他实现也产生了不同的余地,从而产生不同的结果。这个 合同 可能会说你得到的数字来自[0,1]。但在实践中,有相当多的值是永远不会达到的(因为您需要一个生成器中的两个连续值,该生成器可以在连续值之间产生线性依赖关系“状态只有48位”。你不能从那个“至少不是怎么做的”中生成所有不同的53位组合。

    当然,因为 Math.random() 自动播种静态 Random 例如,我们可能还必须考虑到这里的种子, 可以 需要非常具体的测试用例才能解决。这可能意味着准确的时间点可能在几十年或几千年后。

        4
  •  9
  •   Hank Gay    14 年前

    它包含零,不包括一个,例如, [0, 1) 0 <= x < 1 取决于你喜欢哪种符号。

        5
  •  5
  •   Ira Baxter    14 年前

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

    实际上,你可能要等很长时间才能得到 确切地 零。如果随机数生成器实现良好,那么它至少有56位内部状态(否则返回结果的所有位都将不是随机的)。这意味着,如果随机产生的值的分布是平的,那么在2^56中你最多有一次机会得到一个值,所有的位都是零。大约是10-19。我屏住呼吸。

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

        6
  •  2
  •   Mike    14 年前

    从Java API。

    返回带正号的双精度值,大于或等于0.0小于1.0

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

    所以可以。

        7
  •  1
  •   Stephen P    14 年前

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

        8
  •  1
  •   irreputable    14 年前

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

        9
  •  1
  •   Jesse    11 年前

    从理论上讲,math.random()返回零值是可能的,但在现实世界中,您可以指望它实际上永远不会发生。

    有一次我连续运行PC一周等待一个,它产生了大约10万亿个随机数,没有0。

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

        10
  •  0
  •   Viktor Sehr    14 年前

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

    random()返回一个带正号的双精度值,大于或等于0.0小于1.0。

    是的,可以是零,但不能是1。换句话说,比起你的CS教授,更喜欢Java文档。