已知函数ex可以展开为幂级数1+x+x2/2!+x3/3!+⋯+xk/k!+⋯。现给定一个实数x,要求利用此幂级数部分和求ex的近似值,求和一直继续到最后一项的绝对值小于0.00001。
输入格式:
输入在一行中给出一个实数x∈[0,5]。
输出格式:
在一行中输出满足条件的幂级数部分和,保留小数点后四位。
输入样例:
1.2
结尾无空行
输出样例:
3.3201
结尾无空行
错误答案示范:
#include<stdio.h>
#include<math.h>
int main(void)
{
double x;
int i=1,j,fact=1;
scanf("%lf",&x);
double sum=1.0,eps=x;
do{
for(j=1;j<=i;j++)
{
fact*=j;
}
eps = pow(x,i)*1.0/fact;
fact=1;
sum += eps;
i++;
}while(eps>=0.00001);
if(eps==0.00001)
{
for(j=1;j<=i;i++)
{
fact*=j;
}
eps= pow(x,i)*1.0/fact;
sum+=eps;
}
printf("%.4f",sum);
return 0;
}
解析:此题在于使用的不单单是一个阶乘或者一个多次幂,而是对于这二者的算式结果的判断。当输入最大值为5时,结果为负,对此输出结果研究可以知道,必然是分子或者分母其中一个已经溢出,所以变为负数,将此时的i也输出可以知道其值为18,那么最后一次的fact值就为17!,计算可得已经远远大于int的最大值2^32-1,所以出现负数情况,那么就需要改变其取值范围,将其改为都为double类型,就能避免情况的发生。
虽然此答案不正确,但是最后的语句加上if判断本人认为有必要,这涉及到极端情况:输出是这个分式的值恰好等于界值eps,但是题目要求最后一项要小于,所以需要补上一项。
正确代码如下:
#include<stdio.h>
#include<math.h>
int main(void)
{
double x;
int i=1,j;
double fact=1;
scanf("%lf",&x);
double sum=1.0,eps=x;
do{
for(j=1;j<=i;j++)
{
fact*=j;
}
eps = pow(x,i)*1.0/fact;
fact=1;
sum += eps;
i++;
}while(eps>=0.00001);
if(eps==0.00001)
{
for(j=1;j<=i;i++)
{
fact*=j;
}
eps= pow(x,i)*1.0/fact;
sum+=eps;
}
printf("%.4f ",sum);
return 0;
}
当然计算幂与阶乘所用的代码虽然直观,但是不够简洁,大部分朋友用的迭代(算是迭代吧,有点这个思想的味道在里面),就是用第x-1项的结果辅助求出第x项,方法比笔者的好,也很简洁。