DEV Community

Discussion on: 10 Practical JavaScript Tricks

 
zachlitz profile image
Zach • Edited

First, this is all hypothetical. I already agreed that is doesn't matter.

But you are wrong in your premise. Assuming the PRNG was perfectly uniform, the fact that 1 is not included in the interval DOES AFFECT the shuffling. It doesn't matter that 0.999999 = 1.

Let's make the assumption that the PRNG is ideally uniform (otherwise nothing else matters).
Then let's make a list of every number that can be represented in JavaScript as an IEEE754 double precision FP number (which is what Math.random() returns)

The set is written in hex, but it starts like

0x0000000000000001 = 4.94065645841246544176568792868E-324

0x0000000000000002 = 9.88131291682493088353137585736E-324
...
0x3FEFFFFFFFFFFFFF = 9.99999999999999888977697537484E-1 (closest number to 1 before 1)
0x3FF0000000000000 = 1

set a = {
0x0000000000000001, 0x0000000000000002, 0x0000000000000003, 0x0000000000000004, ....
0x3FEFFFFFFFFFFFFF
}

set b = {
0x0000000000000001, 0x0000000000000002, 0x0000000000000003, 0x0000000000000004, ....
0x3FEFFFFFFFFFFFFF, 0x3FF0000000000000
}

Do you see how set a excludes 1, and set b includes 1?
Now split each set into two 1/2 sets where each half set as equal cardinality (if possible)

Do you agree that the two halves of set a are different than the two sets of set b?

Now, randomly pick any number from the entire sample space. Then choose the half set from a that contains the number, and choose the half set from b that contains the number. Guess what, you will pick the 1/2 set with the more numbers more times than the half set with the less numbers.

This is why it matters if 1 is included. You keep saying that 0.99999999=1 but that doesn't mean anything. In fact, it less than meaningless because all you are saying is the decimal value 0.99999999 is represented as 1 as a 64-bit FP number. You are conflating the decimal representation with the in-memory representation. We are dealing with finite sets of discrete numbers.

My original argument was that sorting using the described method will result in a biased sort.
I have since said that it doesn't matter because even assuming the PRNG was perfectly uniform the bias would be insignificantly small, and even more so, it doesn't matter because the PRNG is a black box that is most likely far from perfectly uniform.

But my original statement is correct. Excluding 1 changes the behavior, unless that change is accounted for.

And you are most likely correct that my solution was not an improvement. The first one was 100% wrong, the second might not do anything because it still has the built flaw of not including 1 in the original random number. But my point wasn't to solve the problem, just to show that it won't result in a uniform sort.