数学结果应为零,但与直接替换相比略有偏差

时间:2012-03-18 16:42:28

标签: python

更新:谢谢大家,我没有意识到它非常接近零但不完全为零。有没有办法解决它,所以我的程序将其视为零?它抛出了我的结果,因为这个值没有被提取为零。 Update2:想通了,添加:

from decimal import *
getcontext().prec = 6

然后十进制(数字)修复它。谢谢大家!

我正在运行一段简单的代码但是却得到了一个特定数字的奇怪结果。它有点奇怪,因为当我在python终端中运行相同的命令时,我得到了我期望的结果。

我制作了print语句,命令运行,所以我可以将它复制/粘贴到解释器(python 2.7)中,看看结果是否相同。这是该计划:

x = 20
for s in range(100 + 1): 
    for c in range(100+1):
        if s == 7:
            print s, '-', (c*0.01), '*', x, ' = ', (s - (c*0.01) * x)

结果看起来很好,除了一个:

7 - 0.33 * 20  =  0.4
7 - 0.34 * 20  =  0.2
7 - 0.35 * 20  =  -8.881784197e-16
7 - 0.36 * 20  =  -0.2
7 - 0.37 * 20  =  -0.4

当我将7 - 0.35 * 20复制/粘贴到解释器中时,我得到0.0这就是我所期望的(程序中的其他结果似乎很好,除了7 - 0.35 * 20和(未显示)类似的值14。

我有点难过,我不是这里发生的事情。

5 个答案:

答案 0 :(得分:4)

  

不幸的是,大多数小数部分不能完全表示为   二进制分数。结果是,一般来说,十进制   您输入的浮点数仅由二进制近似   实际存储在机器中的浮点数。

Floating Point Arithmetic: Issues and Limitations

答案 1 :(得分:4)

交互式解释器的输出与您的程序之间没有区别,但是您给它提供了不同的输入。观察:

>>> print 7 - 0.35 * 20
0.0
>>> print 7 - 35 * 0.01 * 20
-8.881784197e-16

正如其他人已经指出的那样,这是由于舍入误差造成的。

答案 2 :(得分:3)

您已经发现(IEEE 754)浮点数学的不精确性质。您计算的结果非常接近于零,但它并不完全为零,因为微处理器通常会以某种方式进行浮点数学运算,从而牺牲一些精度来实现速度和紧凑存储等其他好处。

如何打印这个非常接近零的值可能取决于您以非交互方式使用的Python版本(也是2.7?)。

答案 3 :(得分:2)

你应该决定你希望你的号码接近零,然后检查它。

>>> import numpy as np
>>> is_float_zero = lambda x, eps=np.finfo(float).eps: np.abs(x) < eps
>>> is_float_zero(1e-10)
False
>>> is_float_zero(1e-20)
True

eps是浮点数的精度。您需要根据您对数字进行的处理量来增加此值。请注意,将小数精度设置为6可以提高精确度!

答案 4 :(得分:1)

-8.881784197e-16(-8.8 * 10 ^( - 16))非常接近0.您遇到浮点精度错误。

这是因为你并没有像你认为的那样7 - 0.35 * 20。您正在打印35 * 0.01,看起来像0.35,但不是。

>>> 7 - (0.35 * 20)
0

>>> 7 - (35*0.01 * 20)
-8.881784197001252e-16

>>> 35*0.01
0.35000000000000003