3次元空間の点を表すクラスVectorがあります。このベクトルには、normalize(self, length = 1)
になるようにベクトルを拡大/縮小するメソッドlength == vec.normalize(length).length
があります。
このメソッドのユニットテスト時々は、浮動小数点数の不正確さのために失敗します。私の質問は、メソッドが正しく実装されているときにこのテストが失敗しないことをどのように確認できますか? withoutおおよその値をテストすることは可能ですか?
追加情報:
_ def testNormalize(self):
vec = Vector(random.random(), random.random(), random.random())
self.assertEqual(vec.normalize(5).length, 5)
_
このsometimesは、結果として_AssertionError: 4.999999999999999 != 5
_または_AssertionError: 5.000000000000001 != 5
_になります。
注:浮動小数点の問題は_Vector.length
_プロパティまたはVector.normalize()
にある可能性があることを認識しています。
assertAlmostEqual
、assertNotAlmostEqual
を使用します。
公式ドキュメント から:
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
差を計算し、指定された小数点以下の桁数(デフォルトは7)に丸め、ゼロと比較することにより、1番目と2番目がほぼ等しいことをテストします
本質的にいいえ.
浮動小数点の問題 はバイパスできないため、vec.normalize
で指定された結果を「丸め」るか、ほぼ等しい結果を受け入れる必要があります(2つとも近似値です) )。
浮動小数点値を使用することで、小さな可能性のある不正確さを受け入れます。したがって、テストでは、計算された値が次のような許容範囲内にあるかどうかをテストする必要があります。
theoreticalValue - epsilon < normalizedValue < theoreticalValue + epsilon
ここで、epsilon
は、浮動小数点の不正確さによる変動を許容できると定義する非常に小さな値です。
1つの可能性は、すべての入力、すべての中間計算の結果、および出力がfloat
で正確に表現できるテストケースに関数を適用することです。
説明する:
In [2]: import math
In [4]: def norm(x, y):
...: return math.sqrt(x*x + y*y)
...:
In [6]: norm(3, 4) == 5
Out[6]: True
これがどれほど実用的かはわかりませんが...
一般に、フロートの等価性を主張するべきではありません。代わりに、結果が特定の範囲内にあることを確認してください、例えば:
self.assertTrue(abs(vec.normalize(5).length - 5) < 0.001)