又一个快速三角学

Pab*_*blo 2 c floating-point precision trigonometry numerical-methods

float sinx(float x)
{
    static const float a[] = {-.1666666664,.0083333315,-.0001984090,.0000027526,-.0000000239};
    float xsq = x*x;
    float temp = x*(1 + a[0]*xsq + a[1]*xsq*xsq + a[2]* xsq*xsq*xsq+a[3]*xsq*xsq*xsq*xsq+ a[4]*xsq*xsq*xsq*xsq*xsq);
    return temp;
}
Run Code Online (Sandbox Code Playgroud)

这些常数是如何计算的?如何计算costan使用这种方法?我可以扩展它以获得更高的精度吗?我想我需要添加更多常量?


上面描述的"快速"正弦的误差相对于等度的泰勒多项式的曲线图.

Pas*_*uoq 6

在撰写本文时,几乎所有的答案都指的是函数sin的泰勒展开,但如果函数的作者是严肃的,他就不会使用泰勒系数.泰勒系数倾向于产生多项式近似,其近似于零附近的必要性并且越来越差地远离零.目标通常是获得在-π/ 2 ...π/ 2等范围内均匀良好的近似值.对于多项式近似,这可以通过应用Remez算法来获得.这篇文章是一个脚踏实地的解释.

通过该方法获得的多项式系数接近于泰勒系数,因为两个多项式都试图近似相同的函数,但多项式对于相同数量的操作可能更精确,或者对于相同(均匀)质量涉及更少的操作近似.

如果问题中的系数恰好是泰勒系数或Remez算法得到的略微不同的系数,我不能仅仅通过观察它们来判断,但它可能是应该使用的,即使它不是.

最后,无论谁编写都(1 + a[0]*xsq + a[1]*xsq*xsq + a[2]* xsq*xsq*xsq+a[3]*xsq*xsq*xsq*xsq+ a[4]*xsq*xsq*xsq*xsq*xsq)需要阅读更好的多项式评估方案,例如Horner:

1 + xsq*(a[0]+ xsq*(a[1] + xsq*(a[2] + xsq*(a[3] + xsq*a[4]))))使用N个乘法代替N 2 /2.