From 8cbe9b3f9ba031773aea33e41ba1b7e77802beba Mon Sep 17 00:00:00 2001 From: flatmush Date: Fri, 25 Feb 2011 12:08:03 +0000 Subject: Added fix16_exp currently using the Taylor Series algorithm off Wikipedia, if anyone can optimize this better then go ahead. Modified fixtest to be a little more generic, can now easily change which function it tests. --- fixtest/fixtest.depend | 37 +++++++++++++++++++++++++++++++++++-- fixtest/fixtest.layout | 10 +++++----- fixtest/main.c | 25 ++++++++++++++++++------- libfixmath/fix16.c | 12 ++++-------- libfixmath/fix16.h | 4 ++++ libfixmath/fix16_exp.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ libfixmath/fix16_trig.c | 25 +++++++++++-------------- 7 files changed, 125 insertions(+), 36 deletions(-) create mode 100644 libfixmath/fix16_exp.c diff --git a/fixtest/fixtest.depend b/fixtest/fixtest.depend index db7e8ce..2822106 100644 --- a/fixtest/fixtest.depend +++ b/fixtest/fixtest.depend @@ -1,5 +1,5 @@ # depslib dependency file v1.0 -1298567472 source:g:\vrfx\libfixmath\fixtest\main.c +1298635002 source:g:\vrfx\libfixmath\fixtest\main.c @@ -19,7 +19,7 @@ 1298453688 g:\vrfx\libfixmath\\libfixmath\fract32.h -1298454206 g:\vrfx\libfixmath\\libfixmath\fix16.h +1298634082 g:\vrfx\libfixmath\\libfixmath\fix16.h 1298562746 source:g:\vrfx\libfixmath\fixtest\hiclock.c @@ -32,3 +32,36 @@ +1298567472 source:i:\vrfx\libfixmath\fixtest\main.c + + + + + + + "hiclock.h" + +1298453688 i:\vrfx\libfixmath\\libfixmath\fixmath.h + "uint32.h" + "fract32.h" + "fix16.h" + +1298453688 i:\vrfx\libfixmath\\libfixmath\uint32.h + + +1298453688 i:\vrfx\libfixmath\\libfixmath\fract32.h + + +1298577432 i:\vrfx\libfixmath\\libfixmath\fix16.h + + +1298564182 i:\vrfx\libfixmath\fixtest\hiclock.h + + + + + + +1298562746 source:i:\vrfx\libfixmath\fixtest\hiclock.c + "hiclock.h" + diff --git a/fixtest/fixtest.layout b/fixtest/fixtest.layout index 6606349..36f21e7 100644 --- a/fixtest/fixtest.layout +++ b/fixtest/fixtest.layout @@ -1,13 +1,13 @@ - - + + - + - - + + diff --git a/fixtest/main.c b/fixtest/main.c index a7e9e89..93c945b 100644 --- a/fixtest/main.c +++ b/fixtest/main.c @@ -8,6 +8,17 @@ #include "hiclock.h" +//#define fix_func fix16_exp +//#define fix_func_str "fix16_exp" +//#define flt_func expf +//#define flt_func_str "expf" + +#define fix_func fix16_atan +#define fix_func_str "fix16_atan" +#define flt_func atanf +#define flt_func_str "atanf" + + int main(int argc, char** argv) { printf("libfixmath test tool\n"); @@ -16,7 +27,7 @@ int main(int argc, char** argv) { uintptr_t args = (1 << 8); uintptr_t iter = (1 << 8); - uintptr_t pass = (1 << 8); + uintptr_t pass = (1 << 6); uintptr_t i; srand(time(NULL)); @@ -35,7 +46,7 @@ int main(int argc, char** argv) { for(i = 0; i < iter; i++) { uintptr_t j; for(j = 0; j < args; j++) - fix_result[j] = fix16_atan(fix_args[j]); + fix_result[j] = fix_func(fix_args[j]); } hiclock_t fix_end = hiclock(); @@ -47,7 +58,7 @@ int main(int argc, char** argv) { for(i = 0; i < iter; i++) { uintptr_t j; for(j = 0; j < args; j++) - flt_result[j] = atanf(flt_args[j]); + flt_result[j] = flt_func(flt_args[j]); } hiclock_t flt_end = hiclock(); @@ -57,10 +68,10 @@ int main(int argc, char** argv) { fix_duration += (fix_end - fix_start); } - printf("Floating Point: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", flt_duration, HICLOCKS_PER_SEC); - printf("Fixed Point: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", fix_duration, HICLOCKS_PER_SEC); - printf("Difference: %08"PRIiHICLOCK" (% 3.2f%%)\n", (flt_duration - fix_duration), ((fix_duration * 100.0) / flt_duration)); - printf("Error: %f%%\n", ((fix16_to_dbl(fix_error) * 100.0) / (args * pass))); + printf("% 16s: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", fix_func_str, flt_duration, HICLOCKS_PER_SEC); + printf("% 16s: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", fix_func_str, fix_duration, HICLOCKS_PER_SEC); + printf(" Difference: %08"PRIiHICLOCK" (% 3.2f%%)\n", (flt_duration - fix_duration), ((fix_duration * 100.0) / flt_duration)); + printf(" Error: %f%%\n", ((fix16_to_dbl(fix_error) * 100.0) / (args * pass))); return EXIT_SUCCESS; } diff --git a/libfixmath/fix16.c b/libfixmath/fix16.c index a11e9b7..63cdbc6 100644 --- a/libfixmath/fix16.c +++ b/libfixmath/fix16.c @@ -1,20 +1,16 @@ #include "fix16.h" -/* Replaced as defines, these are left here to uncomment for code dependant on the symbols. +/* Replaced as macros, these are left here to uncomment for code dependant on the symbols. const fix16_t fix16_pi = 205887; const fix16_t fix16_e = 178145; const fix16_t fix16_one = 0x00010000; -*/ - - -/* See header as to why these are commented out. -double fix16_to_dbl(const fix16_t inVal) { return ((double)inVal / 65536.0); } -fix16_t fix16_from_dbl(const double inVal) { return (fix16_t)(inVal * 65536.0); } +double fix16_to_dbl(const fix16_t inVal) { return ((double)inVal / 65536.0); } +fix16_t fix16_from_dbl(const double inVal) { return (fix16_t)(inVal * 65536.0); } float fix16_to_float(const fix16_t inVal) { return ((float)inVal / 65536.0f); } fix16_t fix16_from_float(const float inVal) { return (fix16_t)(inVal * 65536.0f); } -int32_t fix16_to_int(const fix16_t inVal) { return ((inVal + 0x00008000) >> 16); } +int32_t fix16_to_int(const fix16_t inVal) { return ((inVal + 0x00008000) >> 16); } fix16_t fix16_from_int(const int32_t inVal) { return (inVal << 16); } */ diff --git a/libfixmath/fix16.h b/libfixmath/fix16.h index 27e4bc6..9130013 100644 --- a/libfixmath/fix16.h +++ b/libfixmath/fix16.h @@ -111,6 +111,10 @@ extern fix16_t fix16_sqrt(fix16_t inValue); +/*! Returns the exponent (e^) of the given fix16_t. +*/ +extern fix16_t fix16_exp(fix16_t inValue); + #ifdef __cplusplus } #endif diff --git a/libfixmath/fix16_exp.c b/libfixmath/fix16_exp.c new file mode 100644 index 0000000..014fa1c --- /dev/null +++ b/libfixmath/fix16_exp.c @@ -0,0 +1,48 @@ +#include "fix16.h" + + + +#ifndef FIXMATH_NO_CACHE +static fix16_t _fix16_exp_cache_index[4096] = { 0 }; +static fix16_t _fix16_exp_cache_value[4096] = { 0 }; +#endif + + + +fix16_t fix16_exp(fix16_t inValue) { + if(inValue == 0) + return fix16_one; + if(inValue == fix16_one) + return fix16_e; + if(inValue > 681391) + return fix16_MAX; + if(inValue < -726817) + return 0; + + #ifndef FIXMATH_NO_CACHE + fix16_t tempIndex = (inValue ^ (inValue >> 16)); + tempIndex = (inValue ^ (inValue >> 4)) & 0x0FFF; + if(_fix16_exp_cache_index[tempIndex] == inValue) + return _fix16_exp_cache_value[tempIndex]; + #endif + + int64_t tempOut = fix16_one; + tempOut += inValue; + int64_t tempValue = inValue; + uint32_t i, n; + for(i = 3, n = 2; i < 13; n *= i, i++) { + tempValue *= inValue; + #ifndef FIXMATH_NO_ROUNDING + tempValue += (fix16_one >> 1); + #endif + tempValue >>= 16; + tempOut += (tempValue / n); + } + + #ifndef FIXMATH_NO_CACHE + _fix16_exp_cache_index[tempIndex] = inValue; + _fix16_exp_cache_value[tempIndex] = tempOut; + #endif + + return tempOut; +} diff --git a/libfixmath/fix16_trig.c b/libfixmath/fix16_trig.c index 6533a52..67bf80f 100644 --- a/libfixmath/fix16_trig.c +++ b/libfixmath/fix16_trig.c @@ -88,13 +88,12 @@ fix16_t fix16_atan2(fix16_t inY , fix16_t inX) { angle = (4216574283LL * -i) / j; is = (i * i); js = (j * j); - #ifdef FIXMATH_NO_ROUNDING + #ifndef FIXMATH_NO_ROUNDING + is += (fix16_one >> 1); + js += (fix16_one >> 1); + #endif is >>= 16; js >>= 16; - #else - is = (is + (1LL << 15)) >> 16; - js = (js + (1LL << 15)) >> 16; - #endif if((is | js) >> 32) { if((is | js) >> 40) { is >>= 16; @@ -106,21 +105,19 @@ fix16_t fix16_atan2(fix16_t inY , fix16_t inX) { } is = (is * i); js = (js * j); - #ifdef FIXMATH_NO_ROUNDING + #ifndef FIXMATH_NO_ROUNDING + is += (fix16_one >> 1); + js += (fix16_one >> 1); + #endif is >>= 16; js >>= 16; - #else - is = (is + (1LL << 15)) >> 16; - js = (js + (1LL << 15)) >> 16; - #endif is = is * 51472LL; angle += (is / js) << 14; angle += (inX >= 0 ? 3373259426LL : 10119778278LL); - #ifdef FIXMATH_NO_ROUNDING - angle >>= 16; - #else - angle = (angle + (1LL << 15)) >> 16; + #ifndef FIXMATH_NO_ROUNDING + angle += (fix16_one >> 1); #endif + angle >>= 16; angle = (inY < 0 ? -angle : angle); #ifndef FIXMATH_NO_CACHE -- cgit v1.2.3