web-dev-qa-db-ja.com

0に近い値でmath.isclose関数を使用する

ご存知のように、数値のバイナリ表現のため、この式はFalseに評価されます(少なくともPythonでは)。

0.2 + 0.4 == 0.6

数値エラー内で等しいかどうかをチェックできるようにするために、モジュールmathiscloseを提供しています:

import math
math.isclose(0.2 + 0.4 , 0.6)

この最後の式は、期待どおりTrueを生成します。

さてなぜこの次の式は再びFalseになるのですか?

math.isclose(0.2 + 0.4 - 0.6 , 0.0)

0.0と比較したものはすべてFalseのようです

math.isclose(1.0e-100 , 0.0)
11
steffen

答えは ドキュメント を読むことで解決できます。

math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)

値aとbが互いに近い場合はTrueを返し、そうでない場合はFalseを返します。

2つの値が近いと見なされるかどうかは、与えられた絶対許容誤差と相対許容誤差に従って決定されます。

rel_tolは相対許容誤差です。これは、aまたはbの大きい方の絶対値に対する、aとbの間の最大許容差です。たとえば、許容値を5%に設定するには、rel_tol = 0.05を渡します。デフォルトの許容値は1e-09で、2つの値が約9桁以内で同じであることを保証します。 rel_tolはゼロより大きくなければなりません。

abs_tolは最小絶対許容誤差です。ゼロに近い比較に役立ちます。 abs_tolは少なくともゼロでなければなりません。

エラーが発生しない場合、結果は次のようになります。

abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

デフォルトの公差を使用します。これは、相対公差チェックが使用されることを意味します。そして、上記の方程式は、式がfalseと評価される理由を明らかにします。

質問の最後の表現について考えてみましょう。

math.isclose(1.0e-100 , 0.0)

これらの値をドキュメントの式に挿入すると、

1.0e-100 <= max(1.0e-9 * 1.0e-100, 0.0)

デフォルトの許容誤差を使用して相対許容誤差の比較を実行する場合、ゼロ以外の値がゼロに近いと見なされないことは明らかだと思います。

値が非常に小さい場合は、絶対許容値を使用する必要があります。

または、ゼロと比較しないようにテストを書き直す必要があります。

17
David Heffernan