Added a new faster version of the sin function, it loses 0.2% accuracy for a speed gain of 159%. The accuracy of the standard implementation is ~2.1% while this is ~2.3%.

This can be enabled using the FIXMATH_FAST_SIN macro.
This commit is contained in:
flatmush 2011-02-25 13:37:37 +00:00
parent 10c82e1c17
commit 0ecfa08dc3
1 changed files with 44 additions and 0 deletions

View File

@ -26,6 +26,8 @@ fix16_t fix16_sin(fix16_t inAngle) {
fix16_t tempAngleSq = fix16_mul(tempAngle, tempAngle);
#ifndef FIXMATH_FAST_SIN // Most accurate version, accurate to ~2.1%
fix16_t tempOut = tempAngle;
tempAngle = fix16_mul(tempAngle, tempAngleSq);
tempOut -= (tempAngle / 6);
@ -37,6 +39,48 @@ fix16_t fix16_sin(fix16_t inAngle) {
tempOut += (tempAngle / 362880);
tempAngle = fix16_mul(tempAngle, tempAngleSq);
tempOut -= (tempAngle / 39916800);
#else // Fast implementation, runs at 159% the speed of above 'accurate' version with an slightly lower accuracy of ~2.3%
fix16_t tempOut;
tempOut = fix16_mul(-13, tempAngleSq) + 546;
tempOut = fix16_mul(tempOut, tempAngleSq) - 10923;
tempOut = fix16_mul(tempOut, tempAngleSq) + 65536;
tempOut = fix16_mul(tempOut, tempAngle);
#endif
/*// Broken implementation, meant to be slightly faster and much more accurate than the above 'accurate' implementation.
int64_t tempAngleSq = tempAngle * tempAngle;
#ifndef FIXMATH_NO_ROUNDING
tempAngleSq += (fix16_one >> 1);
#endif
tempAngleSq >>= 16;
int64_t tempOut;
tempOut = (-108 * tempAngleSq) + 11836;
#ifndef FIXMATH_NO_ROUNDING
tempOut += (fix16_one >> 1);
#endif
tempOut >>= 16;
tempOut = (tempOut * tempAngleSq) - 852176;
#ifndef FIXMATH_NO_ROUNDING
tempOut += (fix16_one >> 1);
#endif
tempOut >>= 16;
tempOut = (tempOut * tempAngleSq) + 35791394;
#ifndef FIXMATH_NO_ROUNDING
tempOut += (fix16_one >> 1);
#endif
tempOut >>= 16;
tempOut = (tempOut * tempAngleSq) - 715827883;
#ifndef FIXMATH_NO_ROUNDING
tempOut += (fix16_one >> 1);
#endif
tempOut >>= 16;
tempOut = fix16_mul(tempOut, tempAngle) + tempAngle;
*/
#ifndef FIXMATH_NO_CACHE
_fix16_sin_cache_index[tempIndex] = inAngle;