所以,我正在尝试创建一个使用泰勒近似计算cos(x)的程序。
程序非常简单:用户输入一个参数x(x是以弧度表示的角度)和一个浮点ε,它是cos(x)值的精度。
基本上,程序唯一要做的就是计算这个总和: X ^ 0/0! - x ^ 2/2! + x ^ 4/4! - x ^ 6! + x ^ 8/8! - ......,直到这些项小于ε,即cos(x)的值,它将在我们的精度范围内。
所以,这是代码:
#include <stdio.h>
/* Calculates cos(x) by using a Taylor approximation:
cos(x) = x^0/(0!) - x^2/(2!) + x^4/(4!) - x^6/(6!) + x^8/(8!) - ... */
int main(void)
{
int k; // dummy variable k
float x, // parameter of cos(x), in radians
epsilon; // precision of cos(x) (cos = sum ± epsilon)
sum, // sum of the terms of the polynomial series
term; // variable that stores each term of the summation
scanf("%f %f", &x, &epsilon);
sum = term = 1, k = 0;
while (term >= epsilon && -term <= epsilon)
// while abs(term) is smaller than epsilon
{
k += 2;
term *= -(x*x)/(k*(k-1));
sum += term;
}
printf("cos(%f) = %f\n", x, sum);
return 0;
}
起初,我试图通过计算单独变量“fact”的阶乘来解决它,尽管即使ε值合理的大值也会导致溢出。
为了解决这个问题,我注意到我可以将前一个项乘以-x²/(k(k - 1)),在每次迭代中将k增加2,以得到下一个项。我认为这样可以解决我的问题,但话说再来,它无法正常工作。
程序编译很好,但是例如,如果我输入:
3.141593 0.001
输出结果为:
cos(3.141593)= -3.934803
......这显然是错误的。有人能帮助我吗?
答案 0 :(得分:5)
错误在于你的while循环:
while (term >= epsilon && -term <= epsilon)
这不是正确的条件。虽然可以通过修复逻辑来修复:
while (term >= epsilon || -term >= epsilon)
您应该使用标准浮点abs函数fabs
,因为它会使代码的功能更加明显:
while (fabs(term) >= epsilon)
应用该更改并编译程序后,我用它来计算cos(3.141593) = -1.000004
,这是正确的。
答案 1 :(得分:4)
只是加入Charliehorse55的答案。
通常使用简单的三角法来减少参数
cos(x + y) = cos(x)cos(y) - sin(x)sin(y)
sin(x + y) = cos(x)sin(y) + sin(x)cos(y)
将参数减少到[0..SmallAngle]范围,然后才计算泰勒展开。