C:MacLaurin 系列的自动错误检测并与内置的 sinx() 进行比较



Maclaurin Sin X系列

所以主要的想法是使用(difference=builtin func-maclaurin func(并使用do..while循环来增加N。这样它将继续增加N,直到满足最小误差。在这种情况下,我希望最小误差是0.000001,所以它将是while(0.000001<=difference)

但是我写的代码没有正常工作。

#include <stdio.h>
#include <math.h>

int main() {


int a, N=3;
float sum, x, sumbuilt,difference;

printf("enter x in degrees: ");
scanf("%f", &x);
x=x/180*3.14;

printf("degrees in radian: %f ",x );

do
{
sum=x; 
int sign=-1; 
float factorial=1;
//sin x with maclaurin series
for (a = 3; a <=N ; a+=2)
{    
float powersum= 1;
for (int b=1; b<=a; b++)
{
powersum=powersum*(x);
}

factorial=factorial*a*(a-1);
sum= sum + sign* powersum/ factorial;
sign=sign*-1;
}

//sinx with built in function
sumbuilt=sin(x);
difference= sumbuilt-sum;
N++;
}
while(0.000001<=difference)

printf("n sum: %f", sum);
printf("n sum from built: : %f", sumbuilt);


return 0;
}

正如你所看到的,如果我尝试输入x=330,它给出的输出是4.235172,这是完全错误的。应为-0.500147。基本上;当";我放在里面的东西根本没用。

输出4.235172是与如果我设置N=3并且不使用"N"得到的输出相同的输出;当";事物

我不知道我做错了什么。

修复拼写错误后,首先会出现difference可能很大且为负数的错误,因此要检查是否在正确的精度范围内,需要取其绝对值。接下来的问题是,factorial很快变得太大,无法用浮点(甚至双精度(精确表示。

不用构造factorial(一个非常大的数字(和powersum(也可以是一个很大的数字(,你可以记住你在级数中计算的最后一项,然后乘以-x^2,除以阶乘中的新项,得到下一项。这避免了巨大的数字,至少对于x的小值来说是这样。

例如,如果您刚刚计算了x^5/5!,那么下一项就是x^5/5! * -1 * x^2 / (6*7)

这里有一些实现这一点的示例代码(330度的硬编码(:

#include <stdio.h>
#include <math.h>
double macsin(double x, int N) {
double result = x;
double last_term = x;
for (int i = 3; i <= N; i += 2) {
double term = -last_term * x * x / i / (i-1);
result += term;
last_term = term;
}
return result;
}

int main() {
double degrees = 330;
double radians = degrees * M_PI / 180;
printf("%f degrees = %f radiansn", degrees, radians);
double my_sin = 0;
double std_sin = sin(radians);
int N;
for (N = 3; fabs(my_sin - std_sin) > 1e-6; N += 2) {
my_sin = macsin(radians, N);
}
printf("stdlib sin = %fn", std_sin);
printf("maclaurin sin with N=%d = %fn", N, my_sin);
return 0;
}

最新更新