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

しかし、行のコードを に変更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 の概念を誤解している可能性があると思います。この予期しない出力が発生した理由と、この問題を解決する方法を教えてください。

4

2 に答える 2

2

これはオブジェクト指向とは関係ありません。コンピューターが内部で浮動小数点数を表現する方法と、丸め誤差に関係しています。 http://floating-point-gui.de/basic/

ここでの Python の特異性は、浮動小数点数のデフォルトの文字列表現であり、きれいに印刷するための内部表現よりも小数点以下の桁数が少なくなるように丸められます。

ただし、正確な比較が必要な人のために、浮動小数点数のスケールを考慮して、Python はPEP 485math.iscloseで優れたメカニズムを導入し、関数を標準ライブラリに追加しました。

于 2016-08-02T14:06:45.620 に答える