我试图用sineTaylor Series创建一个自定义的c函数来计算这个系列中有10个项的sin,但是当我试图找到sine(x)其中的x > 6时得到了错误的结果。
它对-5 < x < 5很有效,但是超出这个范围的任何东西都不能产生正确的结果。
我希望sin(10)返回一些接近-0.5440的内容,但是得到1418.0269775391
我把所有的东西都放在一个文件里,这样比较容易。

#include <stdio.h>
#include <stdlib.h>

double factorial(double n);
double power(double n, double pow);
double sine(double n);

// This is supposed to all go in a .c file and reference the .h stuff above
// This is the actual implementation of the functions declared above
double factorial(double n) {
    // 0! = 1 so just return it
    if(n == 0) {
        return 1;
    }
    // Recursively call factorial with n-1 until n == 0
    return n * (factorial(n - 1));
}


double power(double n, double power) {
    double result = n;
    // Loop as many times as the power and just multiply itself power amount of times
    for(int i = 1; i < power; i++) {
        result = n * result;
    }
    return result;
}

double sine(double n) {
    double result = n;
    double coefficent = 3; // Increment this by 2 each loop
    for(int i = 0; i < 10; i++) { // Change 10 to go out to more/less terms
        double pow = power(n, coefficent);
        double frac = factorial(coefficent);
        printf("Loop %d:\n%2.3f ^ %2.3f = %2.3f\n", i, n, coefficent, pow);
        printf("%2.3f! = %2.3f\n", coefficent, frac);

        // Switch between adding/subtracting
        if(i % 2 == 0) { // If the index of the loop is divided by 2, the index is even, so subtract
            result = result - (pow/frac); // x - ((x^3)/(3!)) - ((x^5)/(5!))...
        } else {
            result = result + (pow/frac); // x - ((x^3)/(3!)) + ((x^5)/(5!))...
        }
        coefficent = coefficent + 2;
        printf("Result = %2.3f\n\n", result);
    }
    return result;
}

// main starting point. This is suppossed to #include "functions.c" which contain the above functions in it
int main(int argc, char** argv) {

    double number = atof(argv[1]); // argv[1] = "6"
    double sineResult = sine(number);
    printf("%1.10f", sineResult);
    return (0);
}

最佳答案

正如我在Python: Calculate sine/cosine with a precision of up to 1 million digits
以x0为中心的真实泰勒展开式是:
其中Rn是拉格朗日余数
注意,当x偏离中心时,Rn增长很快
x0点。
因为你在实现Maclaurin级数(Taylor级数
以0)为中心,而不是一般的泰勒级数,你的函数
在计算sin(x)时会给出错误的结果
x的大值。
所以在for函数中的sine()循环之前,必须将域至少减少到[-pi,pi]。。。最好把它降到[0,pi]并利用正弦奇偶性。
要修复代码,您需要fmod()中的math.h,因此可以执行以下操作:

#include <math.h>

// Your code

double sine (double n) {
    // Define PI
    const double my_pi = 3.14159265358979323846;
    // Sine's period is 2*PI
    n = fmod(n, 2 * my_pi);
    // Any negative angle can be brought back
    // to it's equivalent positive angle
    if (n < 0) {
        n = 2 * my_pi - n;
    }
    // Sine is an odd function...
    // let's take advantage of it.
    char sign = 1;
    if (n > my_pi) {
        n -= my_pi;
        sign = -1;
    }
    // Now n is in range [0, PI].

    // The rest of your function is fine

    return sign * result;
}

如果你真的讨厌math.h模块,你可以像这样实现自己的fmod()
double fmod(double a, double b)
{
    double frac = a / b;
    int floor = frac > 0 ? (int)frac : (int)(frac - 0.9999999999999999);
    return (a - b * floor);
}

Try it online!

07-27 14:06