What is the granularity of (Math.random())? If I had the following code:
then I'm reasonably sure (iNumber) can have any value between zero inclusive and (intLimit) exclusive completely at random, without any of those numbers being more likely than any other number. But what about:
Is (lNumber) just as likely to be any integer between zero and (longLimit) as another, or are there some (long) values in that range that (lNumber) will never be? And if the latter, what is the highest value (longLimit) can have such that (lNumber) is as likely to be any number in the range from zero to (longLimit) as any other number in that range?
Behind both Math.random() and the Random class is an algorithm to randomly manipulate bits.
Math.random() interprets some of those bits as a double that you can use in your program, typically as a multiplier. If you want to end up with an int then this is probably a workable solution but there will be floating point rounding errors involved so I would expect a minor disturbance in even distribution (I have nothing to actually back this up with though). If you want to get a long out of it then all bets are off because a long is 64 bits but there is fewer than 64 bits being used in the creation of the double.
The Random class is newer and provides more methods that give applications cleaner access to the random bits. For instance, nextInt() does not need to generate an interim floating point number in the process and can use the bits directly. Comparing the Javadocs for nextInt() and nextLong() is interesting in that it says that all the bits of an int will be random, but that not all long values will be possible due to the seed being only 48 bits long. The Random class should be used in preference to Math.random().
Zachary Griggs wrote:. . . Math.random() is actually just a wrapper call to Random.nextDouble() . . .
It always has been. Nothing strange about it. That does mean, in my opinion, that you are usually better going for a Random object.
If you look at Random#nextDouble(), you find it uses 53 bits, which is the precision of a double. The granularity of nextDouble is therefore the same as that of a double: as used by Math#random() it gives you 2⁵³ different values between 0.0...(1 − 2⁻⁵³).
Campbell Ritchie wrote:If you look at Random#nextDouble(), you find it uses 53 bits, which is the precision of a double. The granularity of nextDouble is therefore the same as that of a double: as used by Math#random() it gives you 2⁵³ different values between 0.0...(1 − 2⁻⁵³).
A double may use 53 bits of precision. Random.nextDouble() may set 53 bits. But are all 53 bits "truly" random given the limits of a 48 bit seed? The comment in nextLong() leads me to think it's not.
John von Neumann wrote:
Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin. (1951)
The Art of Computer Programming, Vol II, Semi-Numerical Algorithms, Chapter Three, Random Numbers
"Random", that is, to say more accurately, semi-random numbers, are in fact produced arithmetically. This can actually be an asset in some cases, because when you start with a known seed value, you can precisely reproduce a sequence of known "random" values at will.
Typical random number generators typically case the values as integers, break the integer values into parts by purely mechanical means, then combine the parts according to a certain formula. If you do this properly, the granularity of the resulting pseudo-random value will be the granularity of the primitive type that you are working with.
Some random-number generators attempt to avoid this predictability by introducing external data into the mix. This can be as simple as a quick scan through sections of the computer's RAM known to be volatile and network traffic or as truly random as monitoring radioactive decay (beware of cat hair, though) or interstellar decay. Often these mechanisms also include a "switch" that you can flip so that for testing purposes you get repeatable values while still being abot to obtain more truly random values when you need them.
"privilege" comes from the Latin words for "private" and "law" (legal) and dates to feudal times. To "claim privilege" meant that you were above the laws that applied to the common people.
posted 1 month ago
Carey Brown wrote:. . . are all 53 bits "truly" random . . . .
The 2⁻⁵³ is the granularity of the result; I never said any of the bits is “truly” random at all.
We all know cats are random; I didn't know their hair was more random than the rest of them.