diff options
| author | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-25 12:08:03 +0000 |
|---|---|---|
| committer | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-25 12:08:03 +0000 |
| commit | 8cbe9b3f9ba031773aea33e41ba1b7e77802beba (patch) | |
| tree | f57780d70e9264f9cf13e9dd46a78ac8645a5c41 | |
| parent | 7c2852e7f647ffad35eeda527d4c9d6bff96f226 (diff) | |
| download | libfixmath-8cbe9b3f9ba031773aea33e41ba1b7e77802beba.tar.gz | |
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.
| -rw-r--r-- | fixtest/fixtest.depend | 37 | ||||
| -rw-r--r-- | fixtest/fixtest.layout | 10 | ||||
| -rw-r--r-- | fixtest/main.c | 25 | ||||
| -rw-r--r-- | libfixmath/fix16.c | 12 | ||||
| -rw-r--r-- | libfixmath/fix16.h | 4 | ||||
| -rw-r--r-- | libfixmath/fix16_exp.c | 48 | ||||
| -rw-r--r-- | libfixmath/fix16_trig.c | 25 |
7 files changed, 125 insertions, 36 deletions
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
<stdio.h>
<stdlib.h>
<math.h>
@@ -19,7 +19,7 @@ 1298453688 g:\vrfx\libfixmath\\libfixmath\fract32.h
<stdint.h>
-1298454206 g:\vrfx\libfixmath\\libfixmath\fix16.h
+1298634082 g:\vrfx\libfixmath\\libfixmath\fix16.h
<stdint.h>
1298562746 source:g:\vrfx\libfixmath\fixtest\hiclock.c
@@ -32,3 +32,36 @@ <windows.h>
<time.h>
+1298567472 source:i:\vrfx\libfixmath\fixtest\main.c
+ <stdio.h>
+ <stdlib.h>
+ <math.h>
+ <time.h>
+ <inttypes.h>
+ <libfixmath/fixmath.h>
+ "hiclock.h"
+
+1298453688 i:\vrfx\libfixmath\\libfixmath\fixmath.h
+ "uint32.h"
+ "fract32.h"
+ "fix16.h"
+
+1298453688 i:\vrfx\libfixmath\\libfixmath\uint32.h
+ <stdint.h>
+
+1298453688 i:\vrfx\libfixmath\\libfixmath\fract32.h
+ <stdint.h>
+
+1298577432 i:\vrfx\libfixmath\\libfixmath\fix16.h
+ <stdint.h>
+
+1298564182 i:\vrfx\libfixmath\fixtest\hiclock.h
+ <stdint.h>
+ <inttypes.h>
+ <sys/time.h>
+ <windows.h>
+ <time.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 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <CodeBlocks_layout_file> - <ActiveTarget name="dbg" /> - <File name="hiclock.c" open="1" top="0" tabpos="3"> + <ActiveTarget name="rel" /> + <File name="hiclock.c" open="1" top="0" tabpos="6"> <Cursor position="520" topLine="0" /> </File> - <File name="hiclock.h" open="1" top="0" tabpos="2"> + <File name="hiclock.h" open="1" top="0" tabpos="5"> <Cursor position="578" topLine="0" /> </File> - <File name="main.c" open="1" top="1" tabpos="1"> - <Cursor position="139" topLine="30" /> + <File name="main.c" open="1" top="1" tabpos="4"> + <Cursor position="392" topLine="36" /> </File> </CodeBlocks_layout_file> 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
|
