In this comment in another question, dimo414 states that one of the problems with the OP's code is that it will generate random numbers non-uniformly. So I wonder why this is? Is it inherent the the particular algorithm? Or is it something about Math.random()
itself? Is it because of the floating-point representation of the numbers chosen in the interval [0.0, 1.0)?
p.s. I understand the proposed answer to use Random.nextInt()
. I also want to know more about the flaws of using Math.random()
.
It has almost nothing to do with Math.random()
. The OP's post says all that really needs to be said:
My issue is that on several different attempts, the last card in the
shuffled deck is consistently the same card as the last in the
unshuffled deck.
In other words, the shuffled deck has at least one card in common with the un-shuffled deck every time the code runs. That is most certainly deterministic, not random.
At least one problem with the OP's algorithm is that each iteration multiplies the random number by a smaller number than the previous iteration.
A better approach would have been to create a list of 52 random numbers. Then assign each card in the deck to each element in the list. Then sort the list by the random number and the result is the shuffled deck.
Java's Math.random()
is documented to return numbers that "are chosen pseudorandomly with (approximately) uniform distribution from" the interval [0, 1)
. However, although that documentation specifies that it uses its own java.util.Random
instance, it's not documented how it uses that instance to generate random numbers. For example, it's not documented whether that method will call the nextDouble
method, which is exactly specified for java.util.Random
.