简体   繁体   English

Math.random() === Math.random() 是否有可能

[英]Is it possible for Math.random() === Math.random()

In JavaScript, will this expression ever evaluate to true in any browser?在 JavaScript 中,这个表达式会在任何浏览器中计算为 true 吗? Why or why not?为什么或者为什么不?

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

Note: Please do take the above code literally .注意:请按字面意思理解上面的代码 I'm not asking if Math.random will ever generate duplicate values.我不是在问 Math.random 是否会生成重复值。

Note2: no monkey-patching注意2:没有猴子补丁

This question is about the internal Implementation of Math.random(), not about the nature of random numbers.这个问题是关于 Math.random() 的内部实现,而不是关于随机数的性质。

Will the expression Math.random() === Math.random() ever evaluate to true in any browser?表达式Math.random() === Math.random()在任何浏览器中都会评估为真吗?

Yes, and it's likely to have happened already.是的,而且很可能已经发生了。

This question is about the internal Implementation of Math.random()这个问题是关于Math.random()的内部实现

Well, there isn't a single implementation, every javascript engine does implement its own one.嗯,没有一个单一的实现,每个 javascript 引擎都实现了自己的一个。 It's randomness cannot be trusted , but common engines do/did use 31, 32, 48 or 52 bits of entropy.它的随机性是不可信的,但普通引擎确实/确实使用了 31、32、48 或 52 位的熵。
This means that the probability of getting the same value from two consecutive calls (or, from any two calls) is 2 -31 , 2 -32 etc. That doesn't sound much, but 2 31 is just about the number of internet users…这意味着从连续两次调用(或从任何两次调用中)获得相同值的概率是 2 -31 、 2 -32等。这听起来并不多,但 2 31只是互联网用户的数量…

Oh, and of course there are always bugs like this one哦,当然总是有这样的错误......

Yes.是的。 As long as there's a limit on numeric precision, a random number algorithm always has the possibility of collision (generating two identical values).只要数值精度有限制,随机数算法总是有可能发生冲突(生成两个相同的值)。

JavaScript's Math.random() function returns a random number equal to 0 <= N < 1 . JavaScript 的Math.random()函数返回一个等于0 <= N < 1的随机数。 In the real world, N is theoretically infinite.在现实世界中, N理论上是无限的。 In computing, the limited precision of the result of any random() function results in a finite result set.在计算中,任何random()函数结果的有限精度都会导致有限的结果集。

JavaScript uses signed 64-bit doubles, but the random() function doesn't return negative values. JavaScript 使用有符号的 64 位双精度数,但random()函数不返回负值。 So the maximum range of unique return values is equivalent to a 32-bit unsigned integer.所以唯一返回值的最大范围相当于一个 32 位无符号整数。

Therefore the odds of Math.random() === Math.random() evaluating to true are around 1 in 4294967296^2, or 1 in 1.8e19, or 1 in 18 quintillion.因此Math.random() === Math.random()评估为真的几率大约是 4294967296^2 中的 1,或 1.8e19 中的 1,或 18 quintillion 中的 1。

For this to happen in practice, it would require the function running in a loop and executing one billion times per second ( 1 GHz ) for around 500 years.为了在实践中发生这种情况,需要函数在循环中运行并在大约 500 年内每秒执行 10 亿次(1 GHz)。 Or you could get lucky on your first try.或者,您可能会在第一次尝试时就走运。 ;-) ;-)

Sure it can, assuming something like this is run before hand:当然可以,假设这样的事情事先运行:

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

Otherwise, barring a bug in the browser implementation, it's theoretically possible, but I'd still say the answer to "will this ever evaluate to true" is "no".否则,除非浏览器实现中存在错误,否则理论上是可能的,但我仍然会说“这是否会评估为真”的答案是“否”。 It's just too tiny a probability to realistically ever happen.现实发生的可能性太小了。

For a reasonable implementation, it is true with a probability of approximately 2 −53 .对于合理的实现,它的概率大约为 2 -53

This is because a common way to generate a random double is to evaluate: randomUint53() / (double)(1L << 53) .这是因为生成随机双randomUint53() / (double)(1L << 53)的常用方法是计算: randomUint53() / (double)(1L << 53)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM