【发布时间】:2016-03-23 17:45:06
【问题描述】:
我需要大约 (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;
}
不要介意long double n。 :P 当我不检查当前表达式的值但计算 1000 个或更多表达式时,这很有效。该函数的域是 并且 s() 可以很好地计算 中 x 的近似值。参数越大,计算的误差越大。从 0.6 开始,它超过了准确度。
我不确定问题是否足够清楚,因为我不太了解英语数学语言。问题是 while 条件有什么问题,以及为什么函数 s() 不能正确近似。
编辑: 问题基本解决了。当 x>0 时,我必须从 1 中减去连续表达式的绝对值。
if (x<0)
w += tmp;
else
w -= fabsl(tmp);
在那之后准确度提高了很多(当然是狐狸 x>0)。冗余误差源于长期的双重误差。就这样。还是谢谢你们。
【问题讨论】:
-
如果你想在区间上获得统一的精度,你应该使用使用 Remez 算法而不是 Taylor 确定的多项式。 en.wikipedia.org/wiki/Approximation_theory
-
@Pascal 这最好实现为
sqrt(sqrt(1.0-x)),但这是一个家庭作业。重点不是算法的效率,而是学生实现算法的能力。 -
您是否打开了编译器警告?您是否有 C99 编译器(其中描述了
fabsl)或 C89 编译器(没有fabsl)? -
@pmg,我使用的是 GCC 4.5,在 c89 和 c99 模式下编译。没有任何变化。
-
@Pascal:切比雪夫多项式更容易计算。
标签: c approximation taylor-series