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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3065554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:10:50  来源:igfitidea点击:

Can Java's random function be zero?

javarandom

提问by ThirdD3gree

Just out of curiosity, can Math.random() ever be zero?

出于好奇,Math.random() 可以为零吗?

For example, if I were to have:

例如,如果我有:

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

Would I ever actually get a return of one? There's also rounding error to consider because Math.random() returns a double.

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

I ask because my CS professor stated that random() goes from 0 to 1 inclusive, and I always thought it was exclusive.

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

回答by Angs

Yes, it reallycan be. Math.random()creates a global java.util.Random-generator with seed (System.currentTimeMillis() ^ 0x5DEECE66DL) & ((1L << 48) - 1)and calls nextDouble()for it. If its seed reaches state 107048004364969L(and it will, since java.util.Randomhas full period), the next doublegenerated will be 0.0. Though with bad luck you could end up with the wrong parity in the cycle, because Random.nextDouble()advances the state twice. With little less bad luck you could have to generate 2^47 random numbers before the loop terminates, as I didn't find any other seeds that give 0.0.

是的,它真的可以。Math.random()创建一个java.util.Random带有种子的全局-generator(System.currentTimeMillis() ^ 0x5DEECE66DL) & ((1L << 48) - 1)并调用nextDouble()它。如果它的种子达到状态107048004364969L(并且它会,因为java.util.Random有完整的周期),下一个double生成的将是0.0。虽然运气不好,你可能会在循环中得到错误的奇偶校验,因为 Random.nextDouble()两次推进状态。运气不好的话,你可能不得不在循环终止之前生成 2^47 个随机数,因为我没有找到任何其他种子给0.0.

The seed advances as if by seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);and doubles are generated using 26 and 27 upper bits of two consecutive seed values. In the example the two next seed values will be 0Land 11L.

种子前进就像seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);使用两个连续种子值的 26 位和 27 位高位生成by和 doubles 一样。在示例中,接下来的两个种子值将是0L11L

If you manage to create the global generator with System.currentTimeMillis()==107038380838084L, your code returns immediately. You can simulate this with:

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

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

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

回答by Matt Solnit

According to the documentation, "Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0." This means it can be zero.

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

As Hank wrote, it isexclusive on the upper boundary (can never be 1), so maybe that's where your confusion comes from :-).

正如汉克所写,它在上限上排他性的(永远不会是 1),所以也许这就是您的困惑来自:-)。

回答by Joey

It is perfectly possible that it will never return exactly zero. Java's included PRNG is a 48-bit LCG from which only 32 bits are ever used. For all 53 bits of a doublemantissa to be zero, you'll essentially need at least onecall to next()where the upper 32 bits are zero and another where most of them are. (If I'm not mistaken, I'd say this won't ever happen with how the generator works, but it's late, I'm tired, and I won't bet much on it.)

它完全有可能永远不会返回完全为零。Java 包含的 PRNG 是一个 48 位 LCG,其中只使用了 32 位。要使double尾数的所有 53 位都为零,您基本上需要至少一次调用next()高 32 位为零的位置和其中大多数为零的位置。(如果我没记错的话,我会说发电机的工作方式永远不会发生这种情况,但是已经晚了,我很累,我不会在这上面下太多赌注。)

Since the method documentation explicitly states how random numbers are obtained there is also little leeway for other implementations of the Java runtime to yield different results. The contractmight say that the number you get is from [0, 1). But in practice there are quite a number of values you'll never hit (because you need two successive values from a generator that foribly yields a linear dependency between successive values – there are only 48 bits of state. You can't generate all different 53-bit combinations from that – at least not how it's done.).

由于方法文档明确说明了如何获得随机数,因此 Java 运行时的其他实现也几乎没有产生不同结果的余地。该合约可能会说,你得到的数字是[0,1)。但在实践中,有相当多的值你永远不会命中(因为你需要来自生成器的两个连续值,这两个连续值强制产生连续值之间的线性依赖——只有 48 位状态。你不能生成所有不同的来自那个的 53 位组合 - 至少不是它是如何完成的。)。

Of course, since Math.random()automatically seeds a static Randominstance, we might also have to consider the seed here, which mayneed to be very specific for a test case to work out. And that might mean that that exact point in time could be a few decades or millennia away.

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

回答by Hank Gay

It's inclusive of the zero, exclusive of the one, e.g., [0, 1)or 0 <= x < 1depending on which notation you prefer.

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

回答by Ira Baxter

In theory, it can return the value zero.

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

In practice, you might have to wait an extremely long time to get exactlyzero. If the random number generator is implemented well, it has at least 56 bits of internal state (otherwise all the bits of the returned result will not be random). And that implies, if the distribution of the values produced by random is flat, that you have at most one chance in 2^56 of getting back a value all of whose bits are zero. That's roughly 10^-19. I wouldn't hold my breath.

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

(Others have rightfully observed that as documented, in theory [and presumably in practice] it cannot return the value 1.0).

(其他人已经正确地观察到,正如所记录的那样,理论上[并且可能在实践中]它不能返回值 1.0)。

回答by Mike

From the java API.

来自Java API。

Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0

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

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

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

So yes it can be.

所以是的,它可以。

回答by Stephen P

Math.random() is documentedto return "a double value with a positive sign, greater than or equal to 0.0 and less than 1.0" That is, inclusive of 0.0 but exclusive of 1.0

Math.random() 被记录为返回“带有正号的双精度值,大于或等于 0.0 且小于 1.0”即包含 0.0 但不包含 1.0

回答by irreputable

it is also possible, in a compliant JRE implementation, that it NEVER returns 0.

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

回答by R.W. Derusha

It's theoretically possible for math.random() to return a zero value, but in the real world, you can count on it virtually never happening.

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

I once ran my pc for a week straight waiting for one, it generated about ten trillion random numbers, no zeros.

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

But more directly, it is practically exclusive both ways.

但更直接的是,它实际上是双向的。

回答by Viktor Sehr

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

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

random() Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.

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

Yes, it can be zero, but not 1. In other words, prefer the Java documentation over your CS professor =)

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