为什么 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不可以。
如果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不可以。