我想了解如何使用C double (64位)类型计算函数的前向和后向误差。
例如,如何识别以下函数的前向错误:
double func(double x){
return (pow(x,2.0)/cos(x));
}如果已知相对误差为= 10^-15。
我知道前向误差是精确答案f(x)和计算答案^f(x)之间的值之差。向后误差是用于计算^f(x)的值^x和从^f(x)得到计算值的x的真实值之间的差值。
我的问题是,我不知道如何在实践中计算这些误差。
谢谢。
发布于 2015-10-01 02:38:19
使用扩展精度的样本正向差分。
使用volatile可防止double代码使用扩展精度计算。
#include <assert.h>
#include <float.h>
#include <math.h>
long double func_test_forward(volatile double x) {
#ifdef LDBL_DIG
assert(LDBL_DIG > DBL_DIG);
#endif
volatile double y = func(x);
long double ly = powl(x, 2.0)/cosl(x);
return y - ly;
}发布于 2015-10-01 05:48:46
func()是一个有问题的函数。忽略pow(x,2.0)部件,因为它行为良好。函数的其余部分是1/cos(x)或secant(x),极点是π/2的每一个奇数倍。

假设有一个良好的cos(x),该函数永远不会返回0.0。(从数学上讲,只有cosine(odd*π/2)返回0.0,并且没有double恰好是π/2的奇数倍-所有有限double都是有理的,π不是。)但1/cos(x)的极值将接近odd*π/2,但即便如此,cos()也会有很小的相对误差。理论上:+/-1 ULP。
连同pow()和除法-每个贡献0.5ulp,一个良好的数学库,具有一个非溢出的结果:总误差不超过2ulp。值为x > sqrt(DBL_MAX)时,显然会发生溢出。
现在假设一个不太好的cos(x),odd*π/2附近的选择值可能只返回0.0和INF的割线,所以向前误差是无穷大的。
Argument reduction for huge arguments: Good to the last bit介绍了如何计算好的trig函数
https://stackoverflow.com/questions/32872923
复制相似问题