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;
}