Reputation: 167
If a long and a double are both 8 bytes, why can a long store -9,223,372,036,854,775,808 to 9,223,372,036,854,775,808 and a double can store 1.7*10^308? It seems like something to the 308th power would take a lot more storage. (Sorry it's a short question)
Thanks
Upvotes: 0
Views: 834
Reputation: 26185
Here is a little program that illustrates why double cannot always do long's job correctly. The function test
prints its argument and the results of incrementing it by 1 in each of long and double:
import java.math.BigDecimal;
public strictfp class Test {
public static void main(String[] args) {
test(100);
test(1L << 60);
}
private static void test(long l) {
double d = l;
System.out.println("long "+l + " " + (l + 1) + " double " + new BigDecimal(d) + " " + new BigDecimal(d + 1));
}
}
Output:
long 100 101 double 100 101
long 1152921504606846976 1152921504606846977 double 1152921504606846976 1152921504606846976
With input 100 both are exact, because all integers in that region can be represented exactly in double as well as long.
With input 260 long still gets the exact answer, but double does not, because in that region some integers cannot be represented exactly in double. 260 can, 260+1 cannot.
Upvotes: 1
Reputation: 1623
A double can store exactly as many distinct values as a long because both have the same number of bits. The difference is how the bit patterns are interpreted. For a long this is very simple. If you add one to the bit pattern then the interpreted value changes by one (except for over/underflow). For a double this is more complicated. The bits are separated in multiple parts that represent a base and exponent value. This results in a behavior where the interpreted values of a double aren't distributed equally. You can for example represent very small differences between numbers if the number itself is small, but if the numbers are big, the small differences cannot be represented anymore. e.g. 0.0001 is different from 0.0002 but 1 000 000 000 000 000 000 000.0001 is the same as 1 000 000 000 000 000 000 000.0002.
You can easily test this behavior with the following code.
double a = 0.0001;
double b = 0.0002;
double c = 1_000_000_000_000_000_000_000.0001;
double d = 1_000_000_000_000_000_000_000.0002;
System.out.println(a == b);
System.out.println(c == d);
This will print
false
true
Upvotes: 3