Python基本减法出现错误?

23

可能重复:
Python浮点数舍入误差
Python数学计算错误

我无法让Python正确执行减法1-0.8并分配它。 它一直显示不正确的答案0.19999999999999996。

我进行了一些探索:

sq = {}
sub = {}
for i in range(1000):
    sq[str(i/1000.)+'**2']=((i/1000.)**2)
    sub['1-'+str(i/1000.)]=(1.0-(i/1000.))

我发现这个错误会在0到1的浮点数中的某些随机小组之间发生。当你平方这些浮点数时,也会出现类似的错误,但是属于不同的子集。
我希望能够解释一下这个问题,并告诉如何使Python正确进行算术运算。目前我使用的是round(x,3)方法来解决这个问题,但它并不优雅。
谢谢!
以下是我的Python 2.7.3 shell会话:
*** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win32. ***
*** Remote Python engine  is active ***
>>> 1-0.8
0.19999999999999996
>>> print 1-0.8
0.2
>>> a = 1-0.8
>>> a
0.19999999999999996
>>> print a
0.2
>>> a = 0.2
>>> print a
0.2
>>> a
0.2
>>> 

这是我在一些在线解释器中输入的代码:

def doit():
    d = {'a':1-0.8}
    return d

print doit()

和输出:

{'a': 0.19999999999999996}

3
请查看此链接:http://www.yoda.arachsys.com/csharp/floatingpoint.html - avasal
http://effbot.org/pyfaq/why-are-floating-point-calculations-so-inaccurate.htm - Paul Hankin
3个回答

18

使用Decimal,它专门为此而设计:

>>> from decimal import Decimal, getcontext
>>> Decimal(1) - Decimal(0.8)
Decimal('0.1999999999999999555910790150')
>>> getcontext().prec = 3
>>> Decimal(1) - Decimal(0.8)
Decimal('0.200')
>>> float(Decimal(1) - Decimal(0.8))
0.2

2
你为什么输入浮点数?因为这个原因,第一次减法运算和OP一样存在问题。改用字符串:Decimal(1) - Decimal('0.8') -> Decimal('0.2') - wjandrea
谢谢!我在文档中没有注意到这一点。很有道理,解决了我的问题 :) - Wardy
这无法处理以下情况:float(Decimal(0.061157) - Decimal(0.060782)),它会生成 0.00037500000000000033 - alper

15

浮点数不会像你期望的那样工作。

首先,请阅读浮点数指南。简而言之:计算机将浮点数表示为二进制,事实证明以二进制存储精确的十进制小数是不可能的(试着在纸上尝试一下,看看为什么)。对于实际目的来说,0.19999999999999996足够接近0.2了。如果您想将其打印为0.2,则可以执行以下操作:

print "%0.1f" % floating_point_value

所以你看到的不是错误,这是预期行为。


你对如何在使用 jq 时使用这个解决方法有什么建议吗?我正在使用 jq 进行简单的数学运算,但它在解决简单问题时给出了类似的输出。 - maclian

3

Python使用“位”存储浮点数,有些浮点数无论你拥有多少位的精度,都无法准确表示。这就是你在这里遇到的问题。这有点像用有限的小数位完美准确地写出十进制中的1/3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接