我可以使用什么更准确的算法来计算数字的正弦值?

What is a more accurate algorithm I can use to calculate the sine of a number?

我有这段代码可以计算正弦的猜测值并将其与标准 C 库(在我的例子中是 glibc)的结果进行比较:

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

double double_sin(double a)
{
    a -= (a*a*a)/6;

    return a;
}

int main(void)
{
    double clib_sin = sin(.13),
             my_sin = double_sin(.13);
    printf("%.16f\n%.16f\n%.16f\n", clib_sin, my_sin, clib_sin-my_sin);
    return 0;
}

double_sin 的准确性很差(大约 5-6 位数)。这是我的输出:

0.1296341426196949
0.1296338333333333
0.0000003092863615

如您所见,在 .12963 之后,结果有所不同。

一些注意事项:

我可以使用哪种更准确的算法来计算数字的正弦值?

我有一个类似于 Newton-Raphson 的想法,但是用于计算正弦。 但是,我找不到任何关于它的东西,我排除了这种可能性。

您实际上可以非常接近泰勒级数。诀窍是不要在每次迭代时计算完整的阶乘。

泰勒级数是这样的:

sin(x) = x^1/1! - x^3/3! + x^5/5! - x^7/7!

查看这些项,您通过将分子乘以 x^2、将分母乘以阶乘中的下两个数字并交换符号来计算下一项。然后在添加下一项不会改变结果时停止。

所以你可以这样编码:

double double_sin(double x)
{
    double result = 0;
    double factor = x;
    int i;

    for (i=2; result+factor!=result; i+=2) {
        result += factor;
        factor *= -(x*x)/(i*(i+1));
    }
    return result;
}

我的输出:

0.1296341426196949
0.1296341426196949
-0.0000000000000000

编辑:

如果反向添加项,可以进一步提高准确性,但这意味着计算固定数量的项:

#define FACTORS 30

double double_sin(double x)
{
    double result = 0;
    double factor = x;
    int i, j;
    double factors[FACTORS];

    for (i=2, j=0; j<FACTORS; i+=2, j++) {
        factors[j] = factor;
        factor *= -(x*x)/(i*(i+1));
    }
    for (j=FACTORS-1;j>=0;j--) {
        result += factors[j];
    }
    return result;
}

如果 x 落在 0 到 2*PI 的范围之外,此实现将失去准确性。这可以通过在函数开始时调用 x = fmod(x, 2*M_PI); 来规范化值来解决。