为什么 double 可以存储比 long 多得多的信息? (JAVA)

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

如果long和double都是8字节,为什么long能存-9,223,372,036,854,775,808到9,223,372,036,854,775,808而double能存1.7*10^308?似乎 308 次方的东西会占用更多的存储空间。 (对不起,这是一个简短的问题)

谢谢

double 可以存储与 long 一样多的不同值,因为两者具有相同的位数。不同之处在于位模式的解释方式。长期以来,这很简单。如果您将 1 添加到位模式,则解释值将更改 1(over/underflow 除外)。对于双倍,这更复杂。这些位分为多个部分,表示基数和指数值。这会导致 double 的解释值分布不均的行为。例如,如果数字本身很小,您可以表示数字之间非常小的差异,但如果数字很大,则无法再表示小差异。例如0.0001 与 0.0002 不同,但 1 000 000 000 000 000 000 000.0001 与 1 000 000 000 000 000 000 000.0002 相同。

您可以使用以下代码轻松测试此行为。

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);

这将打印

false
true

这里有一个小程序可以说明为什么 double 不能总是正确地完成 long 的工作。函数 test 打印其参数以及在 long 和 double 中将其递增 1 的结果:

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));
    }
}

输出:

long 100 101 double 100 101
long 1152921504606846976 1152921504606846977 double 1152921504606846976 1152921504606846976

对于输入 100,两者都是精确的,因为该区域中的所有整数都可以用 double 和 long 精确表示。

对于输入 260 long 仍然得到准确的答案,但 double 没有,因为在那个区域有些整数不能用 double 精确表示。 260可以,260+1不可以。