Win a copy of Zero to AI - A non-technical, hype-free guide to prospering in the AI era this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Paul Clapham
  • Bear Bibeault
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • salvin francis
  • Scott Selikoff
  • fred rosenberger

What is the granularity of Math.random()?

 
Ranch Hand
Posts: 224
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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?
 
Saloon Keeper
Posts: 7384
66
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is my understanding...

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().
 
Rancher
Posts: 214
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interestingly, it looks like as of Java 8, that Math.random() is actually just a wrapper call to Random.nextDouble() on a singleton instance of a Random:




Very strange.
 
Marshal
Posts: 70612
288
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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⁻⁵³).

SpeedCrunch wrote:1-2^-53
= 0.99999999999999988898


Edit: tried it with JShell too

jshell> new BigDecimal(Double.longBitsToDouble(Double.doubleToLongBits(1.0) - 1L))
$6 ==> 0.99999999999999988897769753748434595763683319091796875

 
Carey Brown
Saloon Keeper
Posts: 7384
66
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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.
 
Saloon Keeper
Posts: 22638
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Donald Knuth wrote:

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.
 
Campbell Ritchie
Marshal
Posts: 70612
288
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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.
 
Tim Holloway
Saloon Keeper
Posts: 22638
153
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:
We all know cats are random; I didn't know their hair was more random than the rest of them.



Depends on whether you keep them in boxes or not.
 
Everybody's invited. Even this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic