Is it possible for Math.random() === Math.random()

2020-03-30 03:47发布

问题:

In JavaScript, will this expression ever evaluate to true in any browser? 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.

Note2: no monkey-patching

This question is about the internal Implementation of Math.random(), not about the nature of random numbers.

回答1:

Will the expression Math.random() === Math.random() ever evaluate to true in any browser?

Yes, and it's likely to have happened already.

This question is about the internal Implementation of Math.random()

Well, there isn't a single implementation, every javascript engine does implement its own one. It's randomness cannot be trusted, but common engines do/did use 31, 32, 48 or 52 bits of entropy.
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 231 is just about the number of internet users…

Oh, and of course there are always bugs like this one…



回答2:

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. In the real world, N is theoretically infinite. In computing, the limited precision of the result of any random() function results in a finite result set.

JavaScript uses signed 64-bit doubles, but the random() function doesn't return negative values. So the maximum range of unique return values is equivalent to a 32-bit unsigned integer.

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.

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. Or you could get lucky on your first try. ;-)



回答3:

For a reasonable implementation, it is true with a probability of approximately 2−53.

This is because a common way to generate a random double is to evaluate: randomUint53() / (double)(1L << 53).

Example code: java.util.Random.nextDouble().



回答4:

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.