Christopher Lee
Christopher Lee

Reputation: 167

Why can a double store so much more information than a long? (JAVA)

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

Answers (2)

Patricia Shanahan
Patricia Shanahan

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

Jannik
Jannik

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

Related Questions