sin函数与数学库sin相比不准确

sin function not accurate compared to math lib sin

本文关键字:sin 不准确 函数      更新时间:2023-10-16

我一直在尝试实现一个快速但更重要的是准确的自定义sin函数(我不能在项目中使用math.hsin)。当涉及到这种数学时,我不是专家,所以和我XD一起工作。在网上搜索了一下后,我发现了以下代码,在某些情况下,该函数返回了不准确的结果。

float SinF(float X)
{
    float Sine;
    if (X < -3.14159265F) X += 6.28318531F;
    else if (X >  3.14159265F) X -= 6.28318531F;
    if (X < 0)
    {
        Sine = 1.27323954F * X + .405284735F * X * X;
        if (Sine < 0) Sine = .225F * (Sine *-Sine - Sine) + Sine;
        else Sine = .225F * (Sine * Sine - Sine) + Sine;
    }
    else
    {
        Sine = 1.27323954F * X - 0.405284735F * X * X;
        if (Sine < 0) Sine = .225F * (Sine *-Sine - Sine) + Sine;
        else Sine = .225F * (Sine * Sine - Sine) + Sine;
    }
    return Sine;
}

示例:

Bad result example 1:
Value Passed: 1.57079637
Returned Value: 0.999999881
Correct Value: 1.00000000
Bad result example 2:
Value Passed: 1.76704633
Returned Value: 0.980933487
Correct Value: 0.980804682
Bad result example 3:
Value Passed: 1.96329641
Returned Value: 0.924392164
Correct Value: 0.923955679

如有任何帮助,我们将不胜感激。

在这个SO问题中有很多sin和朋友的潜在实现,但通常可以归结为几种常用方法:

  • 内置处理器代码(fsin)
  • 泰勒级数
  • CORDIC
  • 具有可选线性(或更好)插值的查找表(主要用于速度,精度较低)

还有很多其他方法,但这些是我见过的更常见的方法。

还要注意浮点的固有精度限制(如链接到的user657267)。例如,1.57079637不完全是pi/2,因此其sin()可能不完全是1。事实上,你列出的所有"正确"值都不完全准确。你必须决定准确度对你的申请来说足够好。