Python 比较运算符无效,float(1) > float(1) 结果为真,我遗漏了什么?
这不是完全的1大于1,但差不多:
我想比较两个时间戳,如果time > timestamp
这个条件成立,就执行某些操作。两个变量里面的值都是相同的float
类型,从pdb中可以看到这一点。
(Pdb) print time
1396836917.98
(Pdb) print last_timestamp
1396836917.98
(Pdb) if time > last_timestamp: print 'wtf'
wtf
我本以为这个比较会返回False
,看起来这是个float
的问题:
(Pdb) if float(time) > float(last_timestamp): print 'wtf'
wtf
但是int
类型的比较就没问题。
(Pdb) if int(time) > int(last_timestamp): print 'wtf'
所以我猜测可能是因为表示这个数字的位数精度有问题。
(Pdb) if float(time)*100 > float(last_timestamp)*100: print 'wtf'
wtf
但如果没有小数位,比较结果还是会返回True
……
目前我找到的一个解决办法是:
if int(time*100) > int(last_timestamp*100): print 'wtf'
但我真的很想搞清楚到底发生了什么,以及如何正确使用>
运算符来比较float
类型的值……
2 个回答
0
这听起来像是对浮点数的理解问题。
简单来说,除了某些少见的数字,浮点数并不是精确存储数字的,它们存储的数字和你想看到的数字会有一点点差别。比如说,(1-0.8) 实际上并不等于 0.2。
我曾经写过一封关于Java的邮件,但几乎所有编程语言的表现都是一样的:
在Java中尝试计算 (int)(4.1-0.1),你会得到的结果是3。(还有其他使用标准IEEE浮点算法并进行截断整数转换的语言也是如此)
想要更多例子可以看看:
如果你把双精度浮点数转换为单精度浮点数,你会得到一组完全不同的错误值,比如 (int)(4.2f-0.2f) 也会给出错误的结果。
在SQL中也可以说明同样的问题:
select CONVERT(INTEGER, CONVERT(float, 4.1)-CONVERT(float, 0.1))
这会得到结果3。
3
你在用哪个版本的Python呢?print
这个命令会自动调用str
,在旧版本的Python中,这可能会让不同的浮点数看起来一样。你可以试着打印repr(time)
和repr(last_timestamp)
来看看。如果这两个浮点数是不同的,repr
会给它们生成不同的字符串。