我有一个程序可以根据泰勒级数计算反正弦值的近似值。
我和我的 friend 提出了一种算法,该算法能够返回几乎“正确”的值,但我认为我们做得不是很干脆。看一看:
double my_asin(double x)
{
double a = 0;
int i = 0;
double sum = 0;
a = x;
for(i = 1; i < 23500; i++)
{
sum += a;
a = next(a, x, i);
}
}
double next(double a, double x, int i)
{
return a*((my_pow(2*i-1, 2)) / ((2*i)*(2*i+1)*my_pow(x, 2)));
}
我检查了 my_pow 是否正常工作,所以我也没有必要在这里发布它。基本上我希望循环在当前项和下一项之间的差异大于或等于我的 EPSILON (0.00001) 时结束,这是我在计算平方根时使用的精度。
这就是我希望它的工作方式:
while(my_abs(prev_term - next_term) >= EPSILON)
但是函数 double next 依赖于 i,所以我想我也必须在 while 语句中递增它。我应该如何去做这件事有什么想法吗?
-1 的示例输出:
$ -1.5675516116e+00
代替:
$ -1.5707963268e+00
非常感谢你们。
最佳答案
您的代码和问题的问题包括:
- 显示 arcsin 的泰勒级数的图像文件有两个错误:x5 项上有一个减号而不是加号,并且x 显示为 xn 但应该是 x2< i>n+1.
- arcsin 的泰勒级数项中的 x 因子在每个项中增加 x2 ,但是你的公式
a*((my_pow(2*i-1, 2))/((2*i)*(2*i+1)*my_pow(x, 2)))
在每一项中除以 x2。这对于您询问的特定值 -1 无关紧要,但对于除 1 以外的其他值,它会产生错误的结果。 - 您询问如何在术语差异“大于或等于”您的 epsilon 后结束循环,但是,对于 x 的大多数值,您实际上想要小于(或者相反,您想要继续,而不是结束,而差异大于或等于,如您在代码中所示)。
- 泰勒级数是一种糟糕的函数评估方法,因为它的误差会随着您离该级数的中心点越远而增加。大多数像这样的函数的数学库实现都使用极小极大级数或与之相关的东西。
- 从低阶项到高阶项评估序列会导致您先添加较大的值,然后再添加较小的值。由于浮点运算的性质,这意味着较小项的准确性会丢失,因为它被较大的值“推出”了浮点格式的宽度。这种影响将限制任何结果的准确性。
- 最后,为了直接回答您的问题,您构建代码的方式是直接更新
a
,因此您永远不会同时拥有上一个术语和下一个术语。相反,创建另一个double b
以便您有一个对象b
用于前一个术语和一个对象a
用于当前术语,如下所示.
例子:
double a = x, b, sum = a;
int i = 0;
do
{
b = a;
a = next(a, x, ++i);
sum += a;
} while (abs(b-a) > threshold);
关于c - C 中 arcsin 的近似,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20161346/