This is something that's been on my mind for years, but I never took the time to ask before.
Many (pseudo) random number generators generate a random number between 0.0 and 1.0. Mathematically there are infinite numbers in this range, but double
is a floating point number, and therefore has a finite precision.
So the questions are:
- Just how many
double
numbers are there between 0.0 and 1.0? - Are there just as many numbers between 1 and 2? Between 100 and 101? Between 10^100 and 10^100+1?
Note: if it makes a difference, I'm interested in Java's definition of double
in particular.
Others have already explained that there are around 2^62 doubles in the range [0.0, 1.0].
(Not really surprising: there are almost 2^64 distinct finite doubles; of those, half are positive, and roughly half of those are < 1.0.)
But you mention random number generators: note that a random number generator generating numbers between 0.0 and 1.0 cannot in general produce all these numbers; typically it'll only produce numbers of the form n/2^53 with n an integer (see e.g. the Java documentation for nextDouble). So there are usually only around 2^53 (+/-1, depending on which endpoints are included) possible values for the
random()
output. This means that most doubles in [0.0, 1.0] will never be generated.Java
double
s are in IEEE-754 format, therefore they have a 52-bit fraction; between any two adjacent powers of two (inclusive of one and exclusive of the next one), there will therefore be 2 to the 52th power differentdouble
s (i.e., 4503599627370496 of them). For example, that's the number of distinctdouble
s between 0.5 included and 1.0 excluded, and exactly that many also lie between 1.0 included and 2.0 excluded, and so forth.Counting the
doubles
between 0.0 and 1.0 is harder than doing so between powers of two, because there are many powers of two included in that range, and, also, one gets into the thorny issues of denormalized numbers. 10 of the 11 bits of the exponents cover the range in question, so, including denormalized numbers (and I think a few kinds ofNaN
) you'd have 1024 times thedouble
s as lay between powers of two -- no more than2**62
in total anyway. Excluding denormalized &c, I believe the count would be 1023 times2**52
.For an arbitrary range like "100 to 100.1" it's even harder because the upper bound cannot be exactly represented as a
double
(not being an exact multiple of any power of two). As a handy approximation, since the progression between powers of two is linear, you could say that said range is0.1 / 64
th of the span between the surrounding powers of two (64 and 128), so you'd expect aboutdistinct
double
s -- which comes to7036874417766.4004
... give or take one or two;-).Every
double
value whose representation is between0x0000000000000000
and0x3ff0000000000000
lies in the interval [0.0, 1.0]. That's (2^62 - 2^52) distinct values (plus or minus a couple depending on whether you count the endpoints).The interval [1.0, 2.0] corresponds to representations between
0x3ff0000000000000
and0x400000000000000
; that's 2^52 distinct values.The interval [100.0, 101.0] corresponds to representations between
0x4059000000000000
and0x4059400000000000
; that's 2^46 distinct values.There are no doubles between 10^100 and 10^100 + 1. Neither one of those numbers is representable in double precision, and there are no doubles that fall between them. The closest two double precision numbers are:
and
The article Java's new math, Part 2: Floating-point numbers from IBM offers the following code snippet to solve this (in floats, but I suspect it works for doubles as well):
They have this comment about it:
See the wikipedia article for more information.
The Java double is a IEEE 754 binary64 number.
This means that we need to consider:
This basically means there is a total of 2^62-2^52+1 of possible double representations that according to the standard are between 0 and 1. Note that 2^52+1 is to the remove the cases of the non-normalized numbers.
Remember that if mantissa is positive but exponent is negative number is positive but less than 1 :-)
For other numbers it is a bit harder because the edge integer numbers may not representable in a precise manner in the IEEE 754 representation, and because there are other bits used in the exponent to be able represent the numbers, so the larger the number the lower the different values.