这里的舍入错误的本质是什么?

jse*_*old 11 python floating-point

有人可以帮我解开引擎盖下的确切内容吗?

>>> 1e16 + 1.
1e+16
>>> 1e16 + 1.1
1.0000000000000002e+16
Run Code Online (Sandbox Code Playgroud)

我使用的是64位Python 2.7.对于第一个,我会假设因为浮点数只有15的精度,所以它只是四舍五入的错误.真正的浮点答案可能是这样的

10000000000000000.999999....
Run Code Online (Sandbox Code Playgroud)

小数只是被削减了.但第二个结果让我质疑这种理解,不能完全代表?有什么想法吗?

[ 编辑:只是澄清一下.我并不以任何方式暗示答案是"错误的".显然,他们是对的,因为他们是.我只是想了解原因.]

Sti*_*sis 9

它尽可能接近四舍五入.

1e16浮动十六进制是0x4341c37937e08000.

1e16 + 2是0x4341c37937e08001.

在这个数量级上,您可以表示的最小精度差异是2.精确地向下舍入1.0(因为通常IEEE浮点数学将舍入为偶数).添加大于1.0的值将四舍五入到下一个可表示的值.


Eri*_*lle 5

10 ^ 16 = 0x002386f26fc10000可以精确表示为双精度浮点数.下一个可表示的数字是1e16 + 2.1e16 + 1正确舍入到1e16,1e16 + 1.1正确舍入到1e16 + 2.检查此C程序的输出:

#include <stdio.h>
#include <math.h>
#include <stdint.h>

int main()
{
  uint64_t i = 10000000000000000ULL;
  double a = (double)i;
  double b = nextafter(a,1.0e20); // next representable number
  printf("I=0x%016llx\n",i); // 10^16 in hex
  printf("A=%a (%.4f)\n",a,a); // double representation
  printf("B=%a (%.4f)\n",b,b); // next double
}
Run Code Online (Sandbox Code Playgroud)

输出:

I=0x002386f26fc10000
A=0x1.1c37937e08p+53 (10000000000000000.0000)
B=0x1.1c37937e08001p+53 (10000000000000002.0000)
Run Code Online (Sandbox Code Playgroud)