我有一个数值函数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))
?
我只想知道“正确”的方式是什么。