学无止境
我们为梦想前行!

python 表达错误

python表达错误,这一节详细说明 “0.1” 示例,教你怎样自己去精确地分析此类案例。假设这里你已经对浮点数表示有基本的了解。

Representation error 提及事实上有些(实际是大多数)十进制小数不能精确的表示为二进制小数。这是 Python (或 Perl,C,C++,Java,Fortran 以及其它很多)语言往往不能按你期待的样子显示十进制数值的根本原因:

>>> 0.1 + 0.2
0.30000000000000004

这 是为什么?1/10 不能精确的表示为二进制小数。大多数今天的机器(2000 年十一月)使用 IEEE-754 浮点数算法,大多数平台上 Python 将浮点数映射为 IEEE-754 “双精度浮点数”。754 双精度包含 53 位精度,所以计算机努力将输入的 0.1 转为 J/2**N 最接近的二进制小数。J 是一个 53 位的整数。改写:

1 / 10 ~= J / (2**N)

为:

J ~= 2**N / 10

J 重现时正是 53 位(是 >= 2**52 而非 < 2**53),N 的最佳值是 56:

>>> 2**52
4503599627370496
>>> 2**53
9007199254740992
>>> 2**56/10
7205759403792793

因此,56 是保持 J 精度的唯一 N 值。J 最好的近似值是整除的商:

>>> q, r = divmod(2**56, 10)
>>> r
6

因为余数大于 10 的一半,最好的近似是取上界:

>>> q+1
7205759403792794

因此在 754 双精度中 1/10 最好的近似值是是 2**56,或:

7205759403792794 / 72057594037927936

要注意因为我们向上舍入,它其实比 1/10 稍大一点点。如果我们没有向上舍入,它会比 1/10 稍小一点。但是没办法让它恰好是 1/10!

所以计算机永远也不 “知道” 1/10:它遇到上面这个小数,给出它所能得到的最佳的 754 双精度实数:

>>> .1 * 2**56
7205759403792794.0

如果我们用 10**30 除这个小数,会看到它最大30位(截断后的)的十进制值:

>>> 7205759403792794 * 10**30 // 2**56
100000000000000005551115123125L

这表示存储在计算机中的实际值近似等于十进制值 0.100000000000000005551115123125。Python 显示时取 17 位精度为 0。10000000000000001(是的,在任何符合 754 的平台上,都会由其C库转换为这个最佳近似——你的可能不一样!)。

赞(0)
转载请注明出处链接:Pycharm » python 表达错误

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址