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;
}
这些常量是如何计算出来的?如何使用此方法计算cos
和tan
?
我可以扩展它以获得更高的精度吗?我想我需要添加更多常量?
最佳答案
在撰写本文时,几乎所有答案都涉及函数 sin 的泰勒展开,但如果该函数的作者是认真的,他就不会使用泰勒系数。泰勒系数倾向于产生一个多项式近似值,该近似值在零附近比必要的更好,而在远离零的地方越来越差。目标通常是获得在诸如 -π/2…π/2 的范围内一致良好的近似值。对于多项式近似,这可以通过应用 the Remez algorithm 获得。 .一个脚踏实地的解释是this发布。
通过该方法得到的多项式系数接近泰勒系数,因为两个多项式都试图逼近同一个函数,但多项式可能是 对于相同数量的操作更精确,或者对于相同(均匀)的近似质量涉及更少的操作。
我无法仅通过查看它们来判断您问题中的系数是准确的泰勒系数还是 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's :
1 + xsq*(a[0]+ xsq*(a[1] + xsq*(a[2] + xsq*(a[3] + xsq*a[4]))))
使用 N 次乘法而不是 N2/2。
关于c - 另一个快速三角函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13771573/