From 0ecfa08dc392830ab4c52b5c8f26d412575583d4 Mon Sep 17 00:00:00 2001 From: flatmush Date: Fri, 25 Feb 2011 13:37:37 +0000 Subject: 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. --- libfixmath/fix16_trig.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/libfixmath/fix16_trig.c b/libfixmath/fix16_trig.c index 67bf80f..17a5b88 100644 --- a/libfixmath/fix16_trig.c +++ b/libfixmath/fix16_trig.c @@ -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; -- cgit v1.2.3