4

让我们考虑下面的代码

代码:

#!/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

但是,如果我将在线代码更改11foo = 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 的一些概念。请向我解释为什么会发生这种意外输出以及如何解决此问题。

4

2 回答 2

2

这与面向对象无关——它与计算机在内部表示浮点数的方式以及舍入误差有关。 http://floating-point-gui.de/basic/

这里的 Python 特性是浮点数的默认字符串表示形式,它会将它们的小数位四舍五入少于内部表示形式以进行漂亮的打印。

虽然,对于需要正确比较的人,尊重浮点数的比例,Python 引入了一个很好的机制PEP 485,将math.isclose函数添加到标准库中。

于 2016-08-02T14:06:45.620 回答
0

除了 jsbueno 的正确解释之外,请记住 Python 通常允许将“基本类型”转换为自身。

即 str("a") == "a"

因此,如果除了原因之外您还需要解决方法,只需将您的 int/float 混合转换为所有浮点数并测试它们。

a = 2.0 
b = 2 
print "a == b", float(a) == float(b)

输出:

a == b True
于 2016-08-02T20:33:30.350 回答