我需要给定精度的约(1-x)^ 0.25(例如0.0001)。我正在使用expansion found on Wikipedia作为(1 + x)^ 0.25。当当前表达式小于精度时,我需要停止近似。
long double s(long double x, long double d) {
long double w = 1;
long double n = 1; // nth expression in series
long double tmp = 1;
// sum while last expression is greater than accuracy
while (fabsl(tmp) >= d) {
tmp *= (1.25 / n - 1) * (-x); // the next expression
w += tmp; // is added to approximation
n++;
}
return w;
}
不介意长双n。 :P当我没有检查当前表达式的值但是我正在计算1000个或更多表达式时,这很有效。该函数的域是< -1; 1>并且s()计算x in< -1; ~0.6>的近似值。参数越大,计算误差越大。从0.6开始,它超出了准确度。
我不确定这个问题是否足够清楚,因为我不太了解英语数学语言。事情就是条件以及函数s()无法正确逼近的原因。
修改 问题大多解决了。当x> 0时,我必须从1中减去连续表达式的绝对值。
if (x<0)
w += tmp;
else
w -= fabsl(tmp);
之后,准确度增加很多(当然,狐狸x> 0)。冗余错误源于长双重不准确。就这样。无论如何,谢谢你们。
答案 0 :(得分:1)
尝试绘制函数图形
abs((1.0+x)alpha - binomial_formula(alpha,x,tolerance))即使在接近的x范围内,例如[-0.5; 0.5],你会得到类似的东西:
这意味着您的二项式扩展实现不稳定。随着x从零开始越来越远 - 系列必须包含越来越多的术语以获得给定的精度。但是在当前的扩展实现中这样做会导致Catastrophic cancellation发生(一些浮点错误累积机制)。尝试阅读我给出的关于如何设计数值稳定算法的链接。
顺便说一下,谢谢你真正有趣的问题!答案 1 :(得分:1)
你的问题是虽然算法的迭代部分很好,但终止并不是你想象的那样。
当评估无限和时,您正在使用的泰勒级数展开是精确的。但是,您无法评估该无限和并且正在截断。
我想你假设当tmp
小于你想要的容差时,w
中的错误也小于那个容差。
然而,事实并非如此。每次迭代时的错误是剩余项的无限和。这是你扔掉的无数个术语的总和。其中第一个,即tmp
在终止点的值,可能小于您的容差,但它们的总和可能大于您的容差。
当(-x)为负时,你恰好逃脱了它,因为tmp
的交替符号对你有利。当(-x)为正时,当x
接近于零时,你就会侥幸逃脱。
但是,我不相信有一个简单的方法来提出一个简单的通用停止标准。你必须能够对你丢弃的条款加以限制。这现在成为一个数学问题而不是编程问题。