부동 소수점이 부정확하기 때문에 Unittest (때때로)가 실패합니다.
3 차원 공간의 점을 나타내는 벡터 클래스가 있습니다 . 이 벡터에는 normalize(self, length = 1)
벡터를 축소 / 확대 하는 방법 이 있습니다 length == vec.normalize(length).length
.
이 방법 에 대한 단위 테스트는 부동 소수점 숫자의 부정확성 때문에 때때로 실패합니다. 제 질문은 방법이 올바르게 구현되었을 때이 테스트가 실패하지 않도록 어떻게 확인할 수 있습니까? 대략적인 값 을 테스트 하지 않고 할 수 있습니까?
추가 정보 :
def testNormalize(self):
vec = Vector(random.random(), random.random(), random.random())
self.assertEqual(vec.normalize(5).length, 5)
이것은 때때로 중 결과 AssertionError: 4.999999999999999 != 5
나 AssertionError: 5.000000000000001 != 5
.
참고 : 부동 소수점 문제가 Vector.length
속성 또는 Vector.normalize()
.
1) 테스트가 작동하는지 어떻게 확인할 수 있습니까?
사용 assertAlmostEqual
, assertNotAlmostEqual
.
로부터 공식 문서 :
assertAlmostEqual(first, second, places=7, msg=None, delta=None)
차이를 계산하고 주어진 소수점 이하 자릿수 (기본값 7)로 반올림 한 다음 0과 비교하여 첫 번째와 두 번째가 거의 같은지 테스트합니다.
2) 대략적인 값을 테스트하지 않고 할 수 있습니까?
본질적으로 아니요.
부동 소수점 문제는 당신이 주어진다 "라운드"결과에 어느 그래서, 우회 할 수없는 vec.normalize
또는 거의-동일한 결과를 받아 (둘 중 각각의 하나는 근사치입니다).
부동 소수점 값을 사용하면 가능한 작은 부정확성을 허용합니다. 따라서 테스트는 계산 된 값이 다음과 같이 허용 가능한 범위에 속하는지 테스트해야합니다.
theoreticalValue - epsilon < normalizedValue < theoreticalValue + epsilon
어디 epsilon
당신이 때문에 부동 소수점 부정확성에 변형 허용으로 정의하는 것이 매우 작은 값이다.
한 가지 가능성은 모든 입력, 모든 중간 계산의 결과 및 출력이 정확히 표현 가능한 테스트 케이스에 함수를 적용하는 것 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
이것이 얼마나 실용적인지 잘 모르겠습니다 ...
일반적으로 float에 대해 동등성을 주장해서는 안됩니다. 대신 결과가 특정 범위 내에 있는지 확인하십시오. 예 :
self.assertTrue(abs(vec.normalize(5).length - 5) < 0.001)
'program story' 카테고리의 다른 글
한 요소의 모든 속성을 복사하여 다른 요소에 적용하는 방법은 무엇입니까? (0) | 2020.12.08 |
---|---|
IP 주소가 'XXX.XXX.XXX.XX'인 Windows Azure 클라이언트는 서버에 액세스 할 수 없습니다. (0) | 2020.12.08 |
파이썬에서 재귀 적으로 디렉토리를 복사하고 모두 덮어 쓰는 방법? (0) | 2020.12.08 |
위임에 약한 포인터를 사용하는 이유는 무엇입니까? (0) | 2020.12.07 |
Javascript 파일에서 MVC ViewBag 객체에 액세스 할 수 있습니까? (0) | 2020.12.07 |