添加非常小的 Double 值 (Java)

Addition of very small Double values (Java)

我想知道,为什么我简单地添加一些双精度值会导致 Java 中出现以下结果:

double a = 1 + 1E-10; // 1.0000000001 (as expected)
double b = 1 + 1E-15; // 1.000000000000001 (as expected)
double c = 1 + 1E-20; // 1.0 (why?)

我以为我至少可以加上一个Double.MIN_VALUE的值,好像是4.9E-324。

我在这里做错了什么?

你没有做错任何事。小数精度的概念就在眼前。浮点数总是有可能出错的。 并且常见的错误值表示为:

- 1/2E-n <= error <=  1/2E-n

其中 n 是您定义的小数位数。

可以找到更多关于浮点错误的信息here

正如@Turing85 指出的那样,double 有 11 位指数和 53 位尾数。

我们这里计算的是1.0 + 1E-20。为了表示该数字(比 1.0 更精确),我们至少需要 21 位十进制数字的精度或 71 位。这比尾数中提供的 double 更精确。

因此,与 1.0 + 1E-20 最接近的 可表示 double 数字是 .... 1.0。这就是您得到的结果。

欢迎来到神秘的浮点运算世界。