Python浮点数比较

时间:2014-09-29 02:19:50

标签: python floating-point

我只是回顾一些Python的基础知识,并且在比较浮点数方面存在一个棘手的问题。

2.2 * 3.0 == 6.6
3.3 * 2.0 == 6.6

我认为这些都应该返回False。然而,第二个给了我一个真实。 enter image description here

请在这里帮助我。谢谢!

3 个答案:

答案 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.36.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.06.6有所不同是因为它有意义?不,这仅仅是由于乘法中的舍入误差。

一个可行的示例是5.5*2.0 == 2.2*5.0 == 11.0。这里的舍入是有利的