首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java的随机函数可以为零吗?

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

Stack Overflow用户
提问于 2010-06-18 04:53:23
回答 9查看 14K关注 0票数 18

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

例如,如果我有:

代码语言:javascript
复制
while (true){
  if (Math.random() == 0)
    return 1;
}

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

我之所以这样问,是因为我的CS教授指出,random()从0到1(包括0和1),我一直认为它是独占的。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-06-18 04:55:43

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

作为Hank wrote,它在上限上是唯一的(永远不会是1),所以这可能就是你混淆的原因:-)。

票数 22
EN

Stack Overflow用户

发布于 2010-12-07 06:16:17

是的,真的可以。Math.random()使用种子-generator创建全局java.util.Random-generator,并为其调用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);

票数 39
EN

Stack Overflow用户

发布于 2010-06-18 07:22:31

它完全有可能永远不会恰好返回零。Java自带的PRNG是一个48位的LCG,其中只使用了32位。要使double尾数的所有53位都为0,基本上需要至少一次调用next(),其中高32位为0,另一次调用高32位为0。(如果我没记错的话,我会说这永远不会发生在生成器的工作方式上,但是现在已经很晚了,我累了,我不会下太大的赌注。)

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

当然,由于Math.random()会自动为静态Random实例设定种子,因此我们可能还需要考虑此处的种子,它可能需要非常具体才能使测试用例生效。这可能意味着那个确切的时间点可能还需要几十年或几千年的时间。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3065554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档