나는 수치 기능이 f(x, y)구현 몇 가지 공식과 나는 그것이 모든 매개 변수 조합에 대한 분석 표현에 대한 올바른지 확인하려는 이중 부동 소수점 숫자 반환 x과 y나는에 관심이 있습니다. 무엇을 계산하고 비교하는 적절한 방법입니다 분석 부동 소수점 숫자?
두 숫자가 a및 라고 가정 해 보겠습니다 b. 지금까지 절대 abs(a-b) < eps( abs(a-b)/max(abs(a), abs(b)) < eps) 오류 와 상대 ( ) 오류가 모두 eps 미만 인지 확인했습니다 . 그렇게하면 숫자가 1e-20 정도라고해도 수치 부정확성을 잡을 수 있습니다.
그러나 오늘 문제를 발견했습니다. 숫자 값 a과 분석 값 b은 다음 과 같습니다.
In [47]: a
Out[47]: 5.9781943146790832e-322
In [48]: b
Out[48]: 6.0276008792632078e-322
In [50]: abs(a-b)
Out[50]: 4.9406564584124654e-324
In [52]: abs(a-b) / max(a, b)
Out[52]: 0.0081967213114754103
따라서 절대 오차 [50]은 (분명히) 작지만 상대 오차 [52]는 큽니다. 그래서 프로그램에 버그가 있다고 생각했습니다. 디버깅을 통해 이러한 숫자가 비정상 임을 깨달았습니다 . 따라서 적절한 상대 비교를 수행하기 위해 다음 루틴을 작성했습니다.
real(dp) elemental function rel_error(a, b) result(r)
real(dp), intent(in) :: a, b
real(dp) :: m, d
d = abs(a-b)
m = max(abs(a), abs(b))
if (d < tiny(1._dp)) then
r = 0
else
r = d / m
end if
end function
어디 tiny(1._dp)내 컴퓨터에 2.22507385850720138E-308을 반환합니다. 이제 모든 것이 작동하고 상대 오류로 단순히 0을 얻습니다. 특히, 상기 상대 오차 [52]는 틀리며, 이는 비정규 수의 정확도가 불충분하기 때문입니다. 내 구현입니까rel_error함수의 정확합니까? abs(a-b)작은 것보다 작은 지 확인하고 (= 비정상) 0을 반환해야합니까? 아니면 다른 조합을 확인해야
max(abs(a), abs(b))합니까?
나는 "적절한"방법이 무엇인지 알고 싶습니다.
exp(log_gamma(m+0.5_dp) - (m+0.5_dp)*log(t)) / 2m = 234, t = 2000입니다. 내가 증가함에 따라 그것은 빨리 0으로 간다m. 숫자 루틴이 "올바른"숫자 (0을 반환하는 것도 괜찮음)를 12 자리 이상의 유효 숫자로 반환하도록하고 싶습니다. 따라서 계산에서 비정규 숫자를 반환하면 단순히 0이며 문제가 없습니다. 따라서 비교 루틴 만 강력하게해야합니다.