用C中的泰勒级数逼近正弦(x)并且存在很多问题

时间:2017-02-14 02:54:01

标签: c sine taylor-series

我正在尝试使用泰勒级数和斯特林对因子的近似来逼近C中的正弦(x)但是对于任何n => 5,我得到n< 5和-0的非常奇怪的答案。我刚刚开始学习昨天,所以如果一些经验丰富的程序员可以看一看并告诉我什么是错的,我会很感激

泰勒系列正弦

斯特林对因子的近似

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

int main(){

float x,n,s,i,e,p,f,r;
f=M_PI;
e=2.7182818;
s=0;

printf("What value of sine do you want to apporximate?");
    scanf("%f", &x);
printf("With what level of precision do you want to calculate it?");
    scanf("%f", &n);
for(i=0;i<=n; ++i);{
    r=((2*i)+1);
    p=(sqrt(2*r*f)*(pow((r/e),r)));
    s=s+(((pow((-1),i))*(pow(x,((2*i)+1))))/p);
}
printf("the value of sine at %f is %f",x,s);
}

4 个答案:

答案 0 :(得分:0)

这一行

    for(i = 0; i <= n; ++i);{

有一个额外的分号。你正在执行一个空循环。

答案 1 :(得分:0)

在您的配方上使用这是正确的代码,但它会产生错误的输出,因此您需要再次检查您的配方:

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

int main(){

double x,n,s,i,e,p,f;
f=M_PI;
e=2.7182818;
s=0;
int sign=0;// Adding this type to toggle the sign 

printf("What value of sine do you want to apporximate?");
    scanf("%lf", &x);// conversion specifier must be %lf for floating number
printf("With what level of precision do you want to calculate it?");
    scanf("%lf", &n);
for(i=1;i<=n; i=i+2){ // Correcting the for loop
    p=sqrt(2*i*f)*pow((i/e),i); 
    s=s+(pow(-1,sign++)*pow(x,i))/p;
}
printf("the value of sine at %f is %f",x,s);
}

答案 2 :(得分:0)

这更容易兄弟

#include <iostream>
#include <cmath>
using namespace std;
double factorial(int X)
{
    double factorial = 1;
    for(int i=1; i<=X; i++)
    {
        factorial = factorial *i;
    }
    return factorial;
}
double Mysin(double x,double result)
{
        for(int i = 0;i<20;i++)
    {
        result+=pow((-1),i)*pow(x,((2*i)+1))/factorial((2*i)+1);
    }
    return result;
}
double Mycos(double x,double result)
{
    for(int i = 0;i<20;i++)
    {
        result+=pow(-1,i)*pow(x,2*i)/factorial(2*i);
    }
    return result;
}
double Mytan(double sine,double cosine)
{
    return sine/cosine;
}
double deg_to_rad(double x)
{
    double const pi = 3.14159265359;
    return x*pi/180;
}
int main()
{
    double x,result=0;
    cin>>x;
    cout<<"My sin: "<<Mysin(deg_to_rad(x),result)<<endl;
    cout<<"My cosin: "<<Mycos(deg_to_rad(x),result)<<endl;
    cout<<"My tan: "<<Mytan(Mysin(deg_to_rad(x),result),Mycos(deg_to_rad(x),result))<<endl;
    return 0;
}

答案 3 :(得分:-1)

由于sin()是一个周期函数,我不应该超过一个周期来计算它。这简化了太多的数学运算,因为您永远不需要计算大的因子数。实际上,您甚至不需要计算系列中每个项的阶乘,因为系数可以从最后一个导出,只需将先前的系数除以(n-1)n。如果您的输入受限于一个时间段(嗯,您不需要使用M_PI的固定时段,那么您可以让我们说最大值为3.5并且通过将除法模数减少M_PI来减少您对值的答案。

一旦这样说,我们可以绑定您的最大错误,因为3.5的最大输入我们将3.5^n/n!作为我们近似的最后一项,并且对于某些{{1}有界限小于某个最大错误,它修复了我们需要计算的术语数量。

不是试图精确计算所需的术语数量,而是尝试做一些猜测,从导出算法和显示实际值(例如,{{1的最大输入值) }})

这些是n

输入的3.2位置的值
n

所以我们可以停止计算该系列的20个术语。这适用于3.2函数,它添加了所有术语并且是一个简单的函数。对于 n | term at position n for input `3.2` ======+================= 8 | 0.27269634 12 | 0.00240693 16 | 0.00000578 18 | 0.00000019 20 | 0.00000001 21 | 7.9E-10 exp(),如果您认为两者都具有sin()函数的相同项,则可以猜出更好的误差估计(首先,只有奇数项,第二个只有偶数条款)

cos()

exp()表示每个字词都是

 (x^n)/(n!) - (x^(n+2))/((n+2)!) = (n!*x^n*(1 - x^2/((n+1)*(n+2))))/n!

所以我们可以应用与指数相同的标准。

这就是说我们可以在某个时候停止......如果我们继续我们的表格,我们会看到,例如n > 3.2总的累积期限小于< x^n/n! 所以我们可以在那里停下来(至少有n > 30个号码。)

5.3E-18

如果你利用sin函数所具有的对称性,你可以将你的域减少到小于1的double,你甚至可以在幂18的时候停止以获得大约17个有效数字(对于#include <stdio.h> #include <math.h> /* for the system sin() function */ double MySin(double x) /* x must be in the range [0..3.2] */ { int i; const int n = 30; double t = x, acum = x; /* first term, x/1! */ x *= x; /* square the argument so we get x^2 in variable x */ for (i = 3; i < n; i += 2) { t = -t * x / i / (i-1); /* mutiply by -1, x^2 and divide by i and (i-1) */ acum += t; /* and add it to the accum */ } return acum; } int main() { double arg; for(;;) { if (scanf("%lg", &arg) != 1) break; printf("MySin(%lg) = %lg; sin(%lg) = %lg\n", arg, MySin(arg), arg, sin(arg)); } } )来说,你的罪更快。

最后,我们可以通过以下方式获得所有真实域M_PI/4功能的有效性。

double