级数近似实现sin(x)

试着用级数近似的方法实现函数sin(x), 没想到在简单的代码实现过程中出现了一系列的小问题。有必要做些总结和批注。

首先是我的代码

/*Approximate sinx*/

#include 
#include 
//#include 

float sin(float);
float factor(int);
float times(float, int);

int main()
{
    float x;
    scanf_s("%f", &x);
    printf("%f", sin(x));
    system("pause");
    return 0;
}

float factor(int x)
{
    float factor=1;
    for (int i = 1; i <= x; i++)
    {
        factor *= i;
    }
    return factor;
}

float times(float x, int y)
{
    float times=1;
    for (int i = 0; i < y; i++)
    {
        times *= x;
    }
    return times;
}

float sin(float x)
{
    float sinx=0;
    int t = 1;
    for (int i = 1; i <= 20; i++)
    {
        sinx +=t* times(x, 2*i-1) / factor(2*i-1);
        t *= -1;
    }

    return sinx;
}
  • 第一个问题是build error, 原因是我定义的sin(x)函数已经在 里存在了。这是一个很低级的错误,不过我是去了stackflow求助才知道错在哪。一位大哥的回复非常精炼:
    There's a sin function declared in the header file. Just as the error message tells you. You did read it?
    作为一个看不懂报错的家伙,我感到很羞愧。

  • 第二个问题则是runtime error了。输出的数据为-nan(ind)。这里的问题是float精度不够。我的循环体循环到了第50项,小数点位数超过了上限,所以gg了。改为20项,成功。这次解决的方法是google。QvQ

下面则是别人写的代码。我这里为了实现sin(x)的计算,另外定义了阶乘和乘积函数。而在接下来的代码中,作者通过递归思路,极大地简化了表达式,并减少了计算量

#include 
#include 
int main()
{
    float x; // the input value of x 
    float s; //the sum of the expression
    float e; // each item
    scanf_s("%f",&x);
    e = x;
    s = x;
    for (int i = 2; i<1000; i++)
    {
        e = -1*e*x*x / ((2 * i - 1)*(2 * i - 2));// implement the commutative change of sign
        s = s + e;
    }
    
    printf("%f", s);
    system("pause");
    return 0;
}

这里的思路是找相邻两项的关系而非所有项的关系。局部思维versus整体思维。也是很有趣了。

还有一个很显著的特点,是C 编译器体现了非常显著的先后次序关系。这里与java甚至也有不同。前面未声明的变量在后面一定是不能出现的,哪怕是声明在了后面的后面。这也就是把e=x;s=x放在后面而不是直接在header处写明的原因了。

你可能感兴趣的:(级数近似实现sin(x))