浮点问题

yda*_*coR 2 python floating-point floating-accuracy

我知道在大多数编程语言中浮点数并不是100%准确,但我刚才遇到了一个奇怪的问题.我还在学习Python,所以制作了一个简单的程序来计算尽可能少的硬币给出的变化.然而,当它达到0.02时,似乎无法给出2p硬币,而是将其分成2个1p硬币.代码段如下所示:

....
elif amountLeft / 0.02 >= 1:
    changeGiven.append("2p")
    amountLeft -= 0.02
else:
    changeGiven.append("1p")
    amountLeft -= 0.01
Run Code Online (Sandbox Code Playgroud)

我一直在看着它http://www.pythontutor.com并明确有0.02amountLeft对任何事物的最后一次迭代,将转降低到.当我检查时,print 0.02 / 0.02 >= 1True按预期回来了.

我在这里错过了什么明显的东西?

And*_*ark 6

好吧,因为你知道浮点数不是100%准确,所以你不应该发现0.02不能完全表示为Python浮点数.它实际上存储为略高于0.02的值,如果以非常高的精度打印该值,则可以看到:

>>> print '{0:.32f}'.format(0.02)
0.02000000000000000041633363423443
Run Code Online (Sandbox Code Playgroud)

当您不断从变量中减去0.02时,会产生这个小错误.这是一个从1.0开始的例子来说明我在说什么:

>>> x = 1.0
>>> for i in range(49):
...     x -= 0.02
...
>>> x
0.019999999999999383
>>> x / 0.02 >= 1
False
Run Code Online (Sandbox Code Playgroud)

要避免此舍入错误,请使用decimal模块而不是float:

>>> from decimal import Decimal
>>> x = Decimal('1.0')
>>> for i in range(49):
...     x -= Decimal('0.02')
...
>>> x
Decimal('0.02')
>>> x / Decimal('0.02') >= 1
True
Run Code Online (Sandbox Code Playgroud)

或者,将所有值乘以100,使得减去整数2而不是浮点数0.02,这也可以避免舍入误差.