我一直在尝试实现一个快速但更重要的是准确的自定义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。事实上,你列出的所有"正确"值都不完全准确。你必须决定准确度对你的申请来说足够好。