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

Python 数学结果应为零,但与直接替换相比略有偏差,python,Python,更新:谢谢各位,我没意识到它非常接近零,但不完全是零。有没有办法让我的程序将其视为零?因为这个值没有被选为零,所以我的结果会被忽略。 更新2:找到答案,添加: from decimal import * getcontext().prec = 6 然后十进制(数字)修好了。谢谢大家 我正在运行一段简单的代码,但得到了一个带有特定数字的奇怪结果。这有点奇怪,因为当我在python终端中运行相同的命令时,我得到了预期的结果 我制作了print语句,命令正在运行,因此我可以在解释器(Python2.

更新:谢谢各位,我没意识到它非常接近零,但不完全是零。有没有办法让我的程序将其视为零?因为这个值没有被选为零,所以我的结果会被忽略。 更新2:找到答案,添加:

from decimal import *
getcontext().prec = 6
然后十进制(数字)修好了。谢谢大家

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

我制作了print语句,命令正在运行,因此我可以在解释器(Python2.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的类似值)


我有点困惑,我不知道这里发生了什么。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

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

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

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


交互式解释器的输出与您的程序之间没有区别,但您的输入不同。请注意:

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

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

您应该确定您希望您的数字离零有多近,然后进行检查

>>> 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
>>将numpy作为np导入
>>>is_float_zero=lambda x,eps=np.finfo(float.eps:np.abs(x)>>是零浮动(1e-10)
错误的
>>>是零浮动(1e-20)
符合事实的

eps
是浮点数的精度。您需要根据您对数字的处理程度来增加它。请注意,将十进制精度设置为6会丢掉很多精度!

它被称为解释器,而不是中断器。=)@ninjagecko抱歉,safari自动更正了我:-(有什么方法可以在我的程序中解决这个问题吗?基本上我是在检查0,但是-8.881784197e-16没有被我的if语句视为0。@learningJava你的“修复”不是真正的修复——你只是四舍五入到小数点后六位。没有什么需要修复的,因为这不是一个bug!