本题要求实现一个函数,用下列公式求cos(x)的近似值,精确到最后一项的绝对值小于e:
cos(x)=x0/0!−x2/2!+x4/4!−x6/6!+⋯
函数接口定义:
double funcos( double e, double x );
其中用户传入的参数为误差上限e
和自变量x
;函数funcos
应返回用给定公式计算出来、并且满足误差要求的cos(x)的近似值。输入输出均在双精度范围内。
裁判测试程序样例:
#include <stdio.h>
#include <math.h>
double funcos( double e, double x );
int main()
{
double e, x;
scanf("%lf %lf", &e, &x);
printf("cos(%.2f) = %.6f\n", x, funcos(e, x));
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
0.01 -3.14
输出样例:
cos(-3.14) = -0.999899
解题思路:
本题其实就是考我们用函数将 cos x 泰勒展开。 。所以我们需要求出每一项的值,并加起来即可。于是,我们定义 sum 用于计算得数(因为不管 x 等于多少,第一项都是等于1,所以可以直接让 sum=1 ,然后从第二项开始),sum_jc 用于计算每一项的分母的阶乘,用 pow 函数计算每一项的分子,然后 flag 用于保存项前面的符号。
因为当精度特别高时,直接计算阶乘会特别麻烦(提交的时候系统也给了我们提示),所以可以采取另一种计算阶乘的方法,即:保留每次的得数,下一次计算时直接在得数的基础上乘以 i * (i-1) 。
具体代码:
double funcos( double e, double x )
{
double item=1, sum=1, sum_jc=1; //item表示项, sum表示得数, sum_jc表示分母
int flag=-1;//项前的符号
for(int i=2;item>e;i=i+2)
{
sum_jc = sum_jc*i*(i-1);//新的求阶乘的方法
item = pow( x,i )/sum_jc;
sum = sum + flag*item;
flag = -flag;
}
return sum;
}