Math.random()何时开始重复?

时间:2018-10-26 05:29:15

标签: javascript node.js random

我在nodejs中有一个简单的测试,我让它运行了一整夜,无法让Math.random()重复。我意识到这些值(甚至整个序列)迟早会重复,但是对于何时会发生有合理的预期吗?

let v = {};
for (let i = 0;; i++) {
  let r = Math.random();
  if (r in v) break;
  v[r] = r;
}
console.log(i);

2 个答案:

答案 0 :(得分:7)

它是特定于浏览器的:

https://www.ecma-international.org/ecma-262/6.0/#sec-math.random

  

20.2.2.27   Math.random()返回带有正号的Number值,该值大于或等于0但小于1,是随机选择的还是伪选择的   在该范围内以大致均匀的分布随机分布,   使用依赖于实现的算法或策略。该功能   不带参数。

     

为不同代码创建的每个Math.random函数领域必须   通过连续调用产生不同的值序列。

这里的要求只是具有均匀分布的伪随机。

这是来自V8(Chrome和NodeJs的Javascript Engine)的博客文章。

https://v8.dev/blog/math-random

他们说他们正在使用xorshift128+的地方,其最大周期为2^128 -1

答案 1 :(得分:1)

相关(在另一个站点上):Acceptable to rely on random ints being unique?

也非常相关:How many double numbers are there between 0.0 and 1.0?

从数学上讲,在0和1之间有无限数量的实数。但是,Math.Random只能生成有限数量的可能值(因为计算机仅具有有限数量的位来表示数字)。假设它可以生成N个可能的值。然后,通过Pigeonhole Principle,一旦您生成精确的N + 1值,就有100%的机会获得至少一个重复值。

在这一点上,Birthday Paradox证明您应该开始惊奇地快速看到重复项。根据这个“悖论”(这不是真正的悖论,只是违反直觉的),如果一个房间只有23个人,那么他们两个有相同生日的可能性就超过50%。

回到我们的示例,计算该经验的经验法则(请参阅链接的Wikipedia文章)表明,一旦生成大约Math.Random个数字,sqrt(N)就有50%的重复概率。

根据链接的堆栈溢出问题,如果我们假设0到1之间有7,036,874,417,766个数字(如接受的答案所述),(请阅读链接的问题以更详细地说明实际上有多少个是),那么sqrt(7036874417766)刚好超过265.2万,实际上并不是很多。如果真是这样,您大约一个小时内就可以达到50%的概率。不幸的是,即使是每秒10,000,也要花费大约195,468小时才能达到100%的概率。

其他一些答案给出的数字要高得多,所以请选择。