【问题标题】:Is it possible for Math.random() === Math.random()Math.random() === Math.random() 有可能吗
【发布时间】:2015-09-24 06:24:18
【问题描述】:

在 JavaScript 中,这个表达式会在任何浏览器中计算为真吗?为什么或为什么不?

  Math.random() === Math.random()

注意:请按字面意思理解上述代码。我不是在问 Math.random 是否会生成重复值。

注意2:没有猴子补丁

这个问题是关于 Math.random() 的内部实现,而不是关于随机数的性质。

【问题讨论】:

  • 是的,有可能,但不太可能。你为什么问这个?你的意思是“ever”字面意思吗?
  • 问题是同一个数字是否会连续出现两次,这与同一个数字是否会出现两次是不同的。
  • 是的,有可能。在铬浏览器code.google.com/p/chromium/issues/detail?id=276886 上看看这个问题。
  • 同意,但我们知道该算法并不是真正随机的。
  • @vasilenicusor,您的链接显示数字可能会比应有的重复频率更高,但它并不表明连续的数字会重复。

标签: javascript random


【解决方案1】:

表达式Math.random() === Math.random() 会在任何浏览器中计算为真吗?

是的,而且很可能已经发生了。

这个问题是关于Math.random()的内部实现

嗯,没有单一的实现,每个 javascript 引擎都实现了自己的。它是 randomness cannot be trusted,但普通引擎确实/确实使用了 31、32、48 或 52 位熵。
这意味着从两次连续调用(或从任何两次调用)中获得相同值的概率为 2-31、2-32 等。听起来很多,但 231 只是互联网用户的数量……

哦,当然总是有bugs like this one...

【讨论】:

  • 可能已经发生了?您必须指代某个人生成的 32 位数字与其他人过去所做的相同。如果您指的是Math.random() === Math.random() 评估为true 的几率,实际上不太可能。尤其是因为没有理由有人会在程序中使用那行代码。
  • @Beejor:我的意思是Math.random() 调用的结果与该网页上之前的Math.random() 调用相同。所以不是“过去的其他人”,但确实不一定在表达式Math.random() === Math.random()内。
【解决方案2】:

是的。只要数值精度有限制,随机数算法总是有可能发生冲突(生成两个相同的值)。

JavaScript 的Math.random() 函数返回一个等于0 <= N < 1 的随机数。在现实世界中,N 理论上是无限的。在计算中,任何random() 函数结果的有限精度都会导致结果集有限。

JavaScript 使用带符号的 64 位双精度,但 random() 函数不返回负值。所以唯一返回值的最大范围相当于一个 32 位无符号整数。

因此,Math.random() === Math.random() 评估为 true 的几率约为 4294967296^2 中的 1,或 1.8e19 中的 1,或 18 quintillion 中的 1。

要在实践中实现这一点,它需要函数循环运行并每秒执行 10 亿次 (1 GHz) 大约 500 年。或者你可能会在第一次尝试时很幸运。 ;-)

【讨论】:

  • 1 到 2 MHz 似乎更现实。所以与其测试自己,我宁愿把它放在一个流行的网站上,让它的访问者运行脚本 :-) 和发现冲突的人 gets a car of course!
  • 对我来说看起来相当慢......顺便说一句,raise(…) 应该做什么?它也不会停止脚本;甚至不是当前间隔。
  • 回复:raise 看起来他在 JS 中混入了一些 ruby​​ 代码
  • raise 是我的错误;正确的关键字是throw(在紧要关头退出脚本)。不用担心;到达那条线的几率基本上为零!但是,是的,我不确定我对“更快”按钮的想法是什么,因为在 JS 中几乎可以肯定在受到速度冲击之前可以运行多少间隔,例如最大 1ms 共享频率或其他东西。
【解决方案3】:

当然可以,假设事先运行了这样的事情:

Math.random = function () {return 4;}

否则,除非浏览器实现中存在错误,否则 理论上 是可能的,但我仍然会说“这将永远评估为真”的答案是“否”。现实发生的可能性太小了。

【讨论】:

  • 那么,什么是概率,什么是“太小”?在宇宙热寂之前不太可能发生?
  • @Bergi 这取决于函数运行的速率。基于我们拥有像 Seti@Home 这样的东西,它使用了价值 25 亿美元的能源来寻找外星人,也许有人会在几年内启动 Random@Home 项目来让我们发生碰撞。几吨的污染,但是……科学! ;-)
【解决方案4】:
【解决方案5】:

对于一个合理的实现,它是真实的概率大约为 2-53

这是因为生成随机双精度的常用方法是评估:randomUint53() / (double)(1L << 53)

示例代码:java.util.Random.nextDouble().

【讨论】:

  • 你能详细说明你是如何得到这个概率的吗?
  • OP 询问的是 javascript,而不是 java!
  • @ManojKumar:不相关。 Math.random 不返回整数,它返回 0 到 1 之间的双精度数。
  • @Bergi:我不同意你关于 JavaScript 与 Java 的评论。关于这个问题,两种语言的基本概念是相同的。底层的原始随机数生成器将生成整数,并转换为 doubleMath.random()
  • 是的,只是 OP 专门要求 JS 实现。
猜你喜欢
  • 2019-07-12
  • 2015-01-24
  • 1970-01-01
  • 2017-12-04
  • 2011-07-31
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多