为什么比较具有相同值的两个属性类型“float”和“int”在 Python 中得到“False”?
Why comparing two attributes type `float` and `int` with the same values get `False` in Python?
让我们考虑下面的代码
代码:
#!/usr/bin/env python
class Foo():
def __init__(self, b):
self.a = 0.0
self.b = b
def count_a(self):
self.a += 0.1
foo = Foo(1)
for i in range(0, 15):
foo.count_a()
print "a =", foo.a, "b =", foo.b, '"a == b" ->', foo.a == foo.b
输出:
a = 0.2 b = 1 "a == b" -> False
a = 0.4 b = 1 "a == b" -> False
a = 0.6 b = 1 "a == b" -> False
a = 0.8 b = 1 "a == b" -> False
a = 1.0 b = 1 "a == b" -> True
a = 1.2 b = 1 "a == b" -> False
a = 1.4 b = 1 "a == b" -> False
a = 1.6 b = 1 "a == b" -> False
a = 1.8 b = 1 "a == b" -> False
a = 2.0 b = 1 "a == b" -> False
a = 2.2 b = 1 "a == b" -> False
a = 2.4 b = 1 "a == b" -> False
a = 2.6 b = 1 "a == b" -> False
a = 2.8 b = 1 "a == b" -> False
a = 3.0 b = 1 "a == b" -> False
但是如果我将 11
行的代码更改为 foo = Foo(2)
,输出将变为:
a = 0.2 b = 2 "a == b" -> False
a = 0.4 b = 2 "a == b" -> False
a = 0.6 b = 2 "a == b" -> False
a = 0.8 b = 2 "a == b" -> False
a = 1.0 b = 2 "a == b" -> False
a = 1.2 b = 2 "a == b" -> False
a = 1.4 b = 2 "a == b" -> False
a = 1.6 b = 2 "a == b" -> False
a = 1.8 b = 2 "a == b" -> False
a = 2.0 b = 2 "a == b" -> False *
a = 2.2 b = 2 "a == b" -> False
a = 2.4 b = 2 "a == b" -> False
a = 2.6 b = 2 "a == b" -> False
a = 2.8 b = 2 "a == b" -> False
a = 3.0 b = 2 "a == b" -> False
您会看到输出 a = 2.0 b = 2 "a == b" -> False
非常奇怪。我想我可能误解了 Python 中的一些 OOP 概念。请向我解释为什么会出现这种意外输出以及如何解决这个问题。
这与面向对象无关——它与计算机内部表示浮点数的方式和舍入误差有关。
http://floating-point-gui.de/basic/
此处的 Python 特殊性是浮点数的默认字符串表示形式,它将在比内部表示形式更少的小数位舍入它们以进行漂亮打印。
虽然,对于需要正确比较的人,尊重浮点数的比例,Python 引入了一个很好的机制 PEP 485,它在标准中添加了 math.isclose
函数图书馆。
除了 jsbueno 的正确解释外,请记住 Python 通常允许将 "basic types" 转换为自己。
即海峡("a")=="a"
因此,如果除了原因之外您还需要解决方法,只需将您的 int/float 混合转换为所有浮点数并测试它们。
a = 2.0
b = 2
print "a == b", float(a) == float(b)
输出:
a == b True
让我们考虑下面的代码
代码:
#!/usr/bin/env python
class Foo():
def __init__(self, b):
self.a = 0.0
self.b = b
def count_a(self):
self.a += 0.1
foo = Foo(1)
for i in range(0, 15):
foo.count_a()
print "a =", foo.a, "b =", foo.b, '"a == b" ->', foo.a == foo.b
输出:
a = 0.2 b = 1 "a == b" -> False
a = 0.4 b = 1 "a == b" -> False
a = 0.6 b = 1 "a == b" -> False
a = 0.8 b = 1 "a == b" -> False
a = 1.0 b = 1 "a == b" -> True
a = 1.2 b = 1 "a == b" -> False
a = 1.4 b = 1 "a == b" -> False
a = 1.6 b = 1 "a == b" -> False
a = 1.8 b = 1 "a == b" -> False
a = 2.0 b = 1 "a == b" -> False
a = 2.2 b = 1 "a == b" -> False
a = 2.4 b = 1 "a == b" -> False
a = 2.6 b = 1 "a == b" -> False
a = 2.8 b = 1 "a == b" -> False
a = 3.0 b = 1 "a == b" -> False
但是如果我将 11
行的代码更改为 foo = Foo(2)
,输出将变为:
a = 0.2 b = 2 "a == b" -> False
a = 0.4 b = 2 "a == b" -> False
a = 0.6 b = 2 "a == b" -> False
a = 0.8 b = 2 "a == b" -> False
a = 1.0 b = 2 "a == b" -> False
a = 1.2 b = 2 "a == b" -> False
a = 1.4 b = 2 "a == b" -> False
a = 1.6 b = 2 "a == b" -> False
a = 1.8 b = 2 "a == b" -> False
a = 2.0 b = 2 "a == b" -> False *
a = 2.2 b = 2 "a == b" -> False
a = 2.4 b = 2 "a == b" -> False
a = 2.6 b = 2 "a == b" -> False
a = 2.8 b = 2 "a == b" -> False
a = 3.0 b = 2 "a == b" -> False
您会看到输出 a = 2.0 b = 2 "a == b" -> False
非常奇怪。我想我可能误解了 Python 中的一些 OOP 概念。请向我解释为什么会出现这种意外输出以及如何解决这个问题。
这与面向对象无关——它与计算机内部表示浮点数的方式和舍入误差有关。 http://floating-point-gui.de/basic/
此处的 Python 特殊性是浮点数的默认字符串表示形式,它将在比内部表示形式更少的小数位舍入它们以进行漂亮打印。
虽然,对于需要正确比较的人,尊重浮点数的比例,Python 引入了一个很好的机制 PEP 485,它在标准中添加了 math.isclose
函数图书馆。
除了 jsbueno 的正确解释外,请记住 Python 通常允许将 "basic types" 转换为自己。
即海峡("a")=="a"
因此,如果除了原因之外您还需要解决方法,只需将您的 int/float 混合转换为所有浮点数并测试它们。
a = 2.0
b = 2
print "a == b", float(a) == float(b)
输出:
a == b True