diff options
| author | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-28 11:24:38 +0000 |
|---|---|---|
| committer | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-28 11:24:38 +0000 |
| commit | ae58c98283e883898692c9484b62cc1a9ee749e5 (patch) | |
| tree | c37d04eded77616deb99ac0a922d53fd46d8a170 | |
| parent | 8737eb5fe2796f1f550a131e8566d8d667f3024a (diff) | |
| download | libfixmath-ae58c98283e883898692c9484b62cc1a9ee749e5.tar.gz | |
Added 32-bit division option, it is less accurate (inaccuracy of ~0.0035%) and very slow (750% of float) but it does work.
Changed tan to be saturated (i.e. tan(pi/4) = fix16_max rather than divide by zero error), may revert or implement as stan later.
| -rw-r--r-- | libfixmath/fix16.c | 35 | ||||
| -rw-r--r-- | libfixmath/fix16_trig.c | 2 |
2 files changed, 36 insertions, 1 deletions
diff --git a/libfixmath/fix16.c b/libfixmath/fix16.c index 2e3b6d5..88131d8 100644 --- a/libfixmath/fix16.c +++ b/libfixmath/fix16.c @@ -88,6 +88,7 @@ fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) { fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1) {
+ #ifndef FIXMATH_NO_64BIT
int64_t tempResult = inArg0;
tempResult <<= 16;
#ifndef FIXMATH_NO_ROUNDING
@@ -95,6 +96,21 @@ fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1) { #endif
tempResult /= inArg1;
return tempResult;
+ #else
+ int32_t res = (inArg0 / inArg1) << 16;
+ int32_t mod = inArg0 % inArg1;
+ uintptr_t i;
+ for(i = 0; i < 16; i++) {
+ mod <<= 1;
+ res += (mod / inArg1) << (15 - i);
+ mod %= inArg1;
+ }
+ #ifndef FIXMATH_NO_ROUNDING
+ if((mod << 1) / inArg1)
+ res++;
+ #endif
+ return res;
+ #endif
}
fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) {
@@ -103,6 +119,7 @@ fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) { return fix16_MIN;
return fix16_MAX;
}
+ #ifndef FIXMATH_NO_64BIT
int64_t tempResult = inArg0;
tempResult <<= 16;
#ifndef FIXMATH_NO_ROUNDING
@@ -114,6 +131,24 @@ fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) { if(tempResult > fix16_MAX)
return fix16_MAX;
return tempResult;
+ #else
+ int32_t res = (inArg0 / inArg1);
+ if((res < -32768) || (res >= 32768))
+ return (res < 0 ? fix16_MIN : fix16_MAX);
+ res <<= 16;
+ int32_t mod = inArg0 % inArg1;
+ uintptr_t i;
+ for(i = 0; i < 16; i++) {
+ mod <<= 1;
+ res += (mod / inArg1) << (15 - i);
+ mod %= inArg1;
+ }
+ #ifndef FIXMATH_NO_ROUNDING
+ if((mod << 1) / inArg1)
+ res++;
+ #endif
+ return res;
+ #endif
}
diff --git a/libfixmath/fix16_trig.c b/libfixmath/fix16_trig.c index 278a3bd..5d98872 100644 --- a/libfixmath/fix16_trig.c +++ b/libfixmath/fix16_trig.c @@ -115,7 +115,7 @@ fix16_t fix16_cos(fix16_t inAngle) { }
fix16_t fix16_tan(fix16_t inAngle) {
- return fix16_div(fix16_sin(inAngle), fix16_cos(inAngle));
+ return fix16_sdiv(fix16_sin(inAngle), fix16_cos(inAngle));
}
fix16_t fix16_asin(fix16_t inValue) {
|
