Ren*_*ené 4 python floating-point
我是python的新手,我写的是:
t = 0.
while t<4.9:
t = t + 0.1
if t == 1.:
... do something ...
Run Code Online (Sandbox Code Playgroud)
我注意到if语句从未被执行过.所以我修改了代码看起来像这样:
''' Case a'''
t = 0.
while t<4.9:
t = t + 0.1
print(t)
print(t == 5.)
Run Code Online (Sandbox Code Playgroud)
当我运行这个时,我得到:
>>> ================================ RESTART ================================
>>>
5.0
False
Run Code Online (Sandbox Code Playgroud)
这是一个惊喜,因为我希望比较测试为True.然后,我尝试了以下两种情况:
''' Case b'''
t = 0
while t<5:
t = t + 1
print(t)
print(t == 5)
''' Case c'''
t = 0.
while t<5:
t = t + 0.5
print(t)
print(t == 5)
Run Code Online (Sandbox Code Playgroud)
当我运行最后两个案例(b和c)时,最终语句中的比较测试为True.我不明白为什么会这样或为什么行为似乎不一致.我究竟做错了什么?
问题是二进制浮点运算不精确,因此在计算中会出现小错误.特别地,数字0.1没有精确的二进制表示.使用浮点数计算时,非常小的错误会导致结果与您的预期略有不同,这会导致相等测试失败.
使用默认字符串表示形式打印float时,可能无法看到此小错误.请尝试使用repr
,因为这样可以更精确地表示数字(但仍然不是100%准确):
>>> print(repr(t))
4.999999999999998
>>> print(t == 5.)
False
Run Code Online (Sandbox Code Playgroud)
要获得浮点数的准确字符串表示形式,您可以使用以下format
方法:
>>> print '{0:.60f}'.format(t)
4.999999999999998223643160599749535322189331054687500000000000
>>> print '{0:.60f}'.format(0.1)
0.100000000000000005551115123125782702118158340454101562500000
Run Code Online (Sandbox Code Playgroud)
浮点运算的一般规则是永远不要进行相等比较.
当你使用0.5时它工作的原因是因为0.5确实具有二进制浮点数的精确表示,因此在这种情况下你没有看到任何问题.同样,它适用于0.25或0.125.
如果需要精确计算,则可以使用十进制类型.
from decimal import Decimal
step = Decimal('0.1')
t = Decimal(0)
while t < Decimal(5):
t += step
print(t)
print(t == Decimal(5))
Run Code Online (Sandbox Code Playgroud)
结果:
5.0 True
归档时间: |
|
查看次数: |
408 次 |
最近记录: |