首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

log1p(x) 跟 expm1(x) 函数的实现

2013-01-28 
log1p(x) 和 expm1(x) 函数的实现如果我们取前两项作为近结果,那么截断误差大约为 x^3 ,据此可以估算有效

log1p(x) 和 expm1(x) 函数的实现

如果我们取前两项作为近似结果,那么截断误差大约为 x^3 ,据此可以估算有效数字,当然也可以直接计算,我们知道误差最大的点肯定是x=1e-4 时。简单计算一下可知,当x=1e-4 时,用 log(1.0 + x) 计算的 有效数字有12位,用 (-0.5 * x + 1.0) * x 计算的结果的有效数字有 8 位。说明这种方法的有效数字至少可以保证有 8位。对于大多数的计算已经够用了。不过我们的目标是15位有效数字,因此还要再努努力。

上面的方法中泰勒展开只用到了前两项,如果我们多用几项肯定效果会更好。下面我们取前三项。

可以看到这个级数收敛的很快,因此我们只要取很少的几项就能得到很高的计算精度。

下面的代码来自:http://www.johndcook.com/cpp_expm1.html

double expm1(double x){    double y, a = fabs(x);    if (a < DBL_EPSILON) return x;    if (a > 0.697) return exp(x) - 1;  /* negligible cancellation */    if (a > 1e-8)    y = exp(x) - 1;    else /* Taylor expansion, more accurate in this range */    y = (x / 2 + 1) * x;    /* Newton step for solving   log(1 + y) = x   for y : */    /* WARNING: does not work for y ~ -1: bug in 1.5.0 */    y -= (1 + y) * (log1p (y) - x);    return y;}

不过上面的代码中也指出了,当 y 接近 -1 时,也就是 x 为负的很大的数时,上面的方法失效。

很遗憾,直到现在我还没能找到一个让我非常满意的expm1() 函数的实现方式。



热点排行