Python float和int行为

yza*_*avi 3 python floating-point-conversion

当我尝试检查浮点变量是否包含完全整数值时,我得到了下面的奇怪行为.我的代码:

x = 1.7  print x,  (x == int(x))   
x += 0.1  print x,  (x == int(x))
x += 0.1  print x,  (x == int(x))
x += 0.1  print x,  (x == int(x))
print "----------------------"

x = **2.7** print x,  (x == int(x))
x += 0.1  print x,  (x == int(x))
x += 0.1  print x,  (x == int(x))
x += 0.1  print x,  (x == int(x))
Run Code Online (Sandbox Code Playgroud)

我得到了下面的奇怪输出(最后一行是问题):

1.7 False
1.8 False
1.9 False
2.0 True
----------------------
2.7 False
2.8 False
2.9 False
3.0 False
Run Code Online (Sandbox Code Playgroud)

任何想法,为什么2.0true3.0false

lej*_*lot 10

问题不在于转换,而在于添加.

int(3.0) == 3.0
Run Code Online (Sandbox Code Playgroud)

返回True

正如所料.

问题是浮点不是无限精确的,你不能指望2.7 + 0.1*3是3.0

>>> 2.7 + 0.1 + 0.1 + 0.1
3.0000000000000004
>>> 2.7 + 0.1 + 0.1 + 0.1 == 3.0
False
Run Code Online (Sandbox Code Playgroud)

正如@SuperBiasedMan所建议的,值得注意的是,在OPs方法中,由于使用了打印(字符串转换),这个问题在某种程度上被隐藏了,这简化了数据表示以最大限度地提高可读性

>>> print 2.7 + 0.1 + 0.1 + 0.1 
3.0
>>> str(2.7 + 0.1 + 0.1 + 0.1)
'3.0'
>>> repr(2.7 + 0.1 + 0.1 + 0.1)
'3.0000000000000004'
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,这种区别并没有清楚地显示出来,因为`print`会为了可读性而忽略差异,但如果你使用`repr(2.7 + 0.1 + 0.1 + 0.1)`它就会显示出真正的价值. (3认同)