创建自定义正弦函数

标签 c factorial trigonometry taylor-series

我尝试创建自定义 sine功能使用cTaylor Series用于计算 sin系列中有 10 个术语,但是当我尝试查找 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 中所说的那样

The real Taylor expansion centered in x0 is:

where Rn is the Lagrange Remainder

Note that Rn grows fast as soon as x moves away from the center x0.

Since you are implementing the Maclaurin series (Taylor series centered in 0) and not the general Taylor series, your function will give really wrong results when trying to calculate sin(x) for big values of x.

因此,在 sine() 函数中的 for 循环之前,您必须至少将定义域减小到 [-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!

关于创建自定义正弦函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48758757/

相关文章:

javascript - 从方坐标到 CSS matrix3d()

c - 打印特定年份和月份的日历

c - 为什么下面的循环展开会导致错误的结果?

在 C 中计算阶乘会导致错误的答案

c++ - 这段代码是如何工作的?俯仰和偏航

java - Java 三角函数

c - 汇编程序中eax寄存器的值

c - 在c中使用exe文件

math - 找到一个大阶乘数的除数之和?

c - 我的c程序没有给出任何结果。请帮助大家