我只是回顾一些Python的基础知识,并且在比较浮点数方面存在一个棘手的问题。
2.2 * 3.0 == 6.6
3.3 * 2.0 == 6.6
我认为这些都应该返回False。然而,第二个给了我一个真实。
请在这里帮助我。谢谢!
答案 0 :(得分:13)
这可能很有启发性:
>>> float.hex(2.2 * 3.0)
'0x1.a666666666667p+2'
>>> float.hex(3.3 * 2.0)
'0x1.a666666666666p+2'
>>> float.hex(6.6)
'0x1.a666666666666p+2'
虽然它们都以十进制显示为6.6
,但当您检查内部表示时,其中两个以相同的方式表示,而其中一个不是。
答案 1 :(得分:3)
为了完成Amadan的好答案,这里有一个更明显的方式来看到2.2 * 3。和3.3 * 2。不是由相同的float表示:在Python shell中,
>>> 2.2 * 3.
6.6000000000000005
>>> 3.3 * 2.
6.6
实际上,Python shell显示了数字的表示,根据定义,它应该允许从表示中正确地构建相应的float,因此您可以看到2.2 * 3的数值近似值Python确实如此。 2.2 * 3的事实。 != 3.3 * 2。在看到所有必要的数字时很明显,如上所述。
答案 2 :(得分:0)
显然,3.3 * 2.0
在数字上与6.6
相同。后者的计算仅是二进制指数的增量,因为它是乘以2的幂的结果。您可以在下面看到它:
| s exponent significant
----+-------------------------------------------------------------------
1.1 | 0 01111111111 0001100110011001100110011001100110011001100110011010
2.2 | 0 10000000000 0001100110011001100110011001100110011001100110011010
3.3 | 0 10000000000 1010011001100110011001100110011001100110011001100110
6.6 | 0 10000000001 1010011001100110011001100110011001100110011001100110
上面您看到浮点数3.3
和6.6
的二进制表示形式。这两个数的唯一区别是指数,因为它们仅乘以2。我们知道IEEE-754将:
2^53
整数(对于binary64)因此,由于2.0
可以精确表示,因此与该数字相乘将仅是指数的变化。因此,以下所有内容都会创建相同的浮点数:
6.6 == 0.825 * 16.0 == 1.65 * 4.0 == 3.3*2.0 == 13.2 * 0.5 == ...
这是否意味着2.2*3.0
与6.6
有所不同是因为它有意义?不,这仅仅是由于乘法中的舍入误差。
一个可行的示例是5.5*2.0 == 2.2*5.0 == 11.0
。这里的舍入是有利的