【问题描述】
给定一个精度值e,用下列公式计算sin(x)的近似值,要求前后两次迭代之差的绝对值小于e,给出相应的最小迭代次数n和最后一次计算的sin(x)值。
sin x = x - x3/3! + x5/5! - x7/7! + ... + (-1)n-1x2n-1/(2n-1)!
其中x为弧度,n为正整数。
【输入形式】
从控制台输入x( (0
【输出形式】
输出迭代次数n和最后一次计算的sin(x)的值(以一个空格分隔,并且输出sin(x)时要求小数点后保留9位有效数字)。
【样例输入】
1.23 0.0000001
【样例输出】
7 0.942488802
【样例说明】
输入的x为1.23,精度值e为0.0000001。当n为5时,利用上述公式计算sin(x)的值为0.942489044,n为6时计算的结果为0.942488800,两结果之差的绝对值约为0.000000244,大于要求的精度值0.0000001,故需要继续迭代计算。当n为7时计算的结果为0.942488802,与n为6的计算结果之差的绝对值约为0.000000002,小于要求的精度值,所以最小迭代次数应为7,最后一次计算的sin(x)的值为0.942488802(小数点后保留9位有效数字)。
注意:
(1) 为保证计算精度,请使用double数据类型保存计算数据。
(2) 应至少迭代两次,即:n>=2。
n=7时测试数据与我的结果数据差了一点点,思路和其他测试数据都一样,不知道为啥。
#include
#include
int f(int n)
{
int i,sum=1;
for(i=1;i<=n;i++)
{
sum*=i;
}
return sum;
}
int main()
{
double x,e,x2,x3,x4;
scanf("%lf %lf",&x,&e);
x2=x;
x3=1;
x4=x;
int i,j,flag=-1,cnt=1;
for(i=2;x3>=e;i++)
{
x3=x2;
x4*=x*x;
x2=x2+x4*flag/f((2*i-1));
flag=-flag;
x3=fabs(x2-x3);
cnt++;
}
printf("%d %.9lf",cnt,x2);
return 0;
}
我这里把函数f()里面sum的数据类型改为double,结果就和题目所给出的一致了,所以推测应该是求阶乘这里的原因。
修改如下:
参考链接:
#include<stdio.h>
#include<math.h>
double f(int n)
{
int i;
double sum=1;
for(i=1;i<=n;i++)
{
sum*=i;
}
return sum;
}
int main()
{
// https://blog.csdn.net/ZHangFFYY/article/details/53043885
// https://www.jianshu.com/p/67d55d7b1480
double x,e,x2,x3,x4;
scanf("%lf %lf",&x,&e);
x2=x;
x3=1;
x4=x;
int i,j,flag=-1,cnt=1;
for(i=2;x3>=e;i++)
{
x3=x2;
x4*=x*x;
x2=x2+x4*flag/f((2*i-1));
flag=-flag;
x3=fabs(x2-x3);
cnt++;
}
printf("%d %.9lf",cnt,x2);
return 0;
}
我给你进行修改
#include <stdio.h>
#include <math.h>
int main() {
double x, e, sinx = 0, term = 0;
int n = 2;
printf("请输入x和e:\n");
scanf("%lf %lf", &x, &e);
term = x; // n=1时的项
sinx = term;
do {
term *= -x * x / ((2 * n - 1) * (2 * n - 2));
sinx += term;
n++;
} while (fabs(term) >= e);
printf("迭代次数n为:%d,最后一次计算的sin(x)的值为:%.9lf\n", n-1, sinx);
return 0;
}
算法思路:
1.读入x和e的值
2.将term初始值赋为x,sinx初始值赋为term,n的初值为2,这个是因为题目要求起始迭代次数至少为2.
3.用do-while循环计算每一项的值并累加到sinx中,直到满足精度要求(fabsterm < e),每次循环都是在前一项的基础上计算得到当前项的值。
不知道你这个问题是否已经解决, 如果还没有解决的话: