From 30419b63d7da9c397fb84e4c3a4db704ad12ac34 Mon Sep 17 00:00:00 2001 From: RicoP Date: Sat, 14 Mar 2020 12:17:26 +0100 Subject: [PATCH 1/4] Fix some template types to be compatible with numeric types bigger than sizeof(int) --- include/EAStdC/EAFixedPoint.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/EAStdC/EAFixedPoint.h b/include/EAStdC/EAFixedPoint.h index 5bb2a0e..c5b5391 100644 --- a/include/EAStdC/EAFixedPoint.h +++ b/include/EAStdC/EAFixedPoint.h @@ -134,12 +134,12 @@ namespace StdC /////////////////////////////////////////////////////////////////////////////// // class FPTemplate // -#define FPTemplateDeclaration template +#define FPTemplateDeclaration template #define FPTemplateType FPTemplate template + T upShiftInt, T downShiftInt, + T upMulInt, T downDivInt> struct FPTemplate { @@ -152,10 +152,10 @@ struct FPTemplate //Functions FPTemplate() {} FPTemplate(const FPTemplate& newValue) { value = newValue.value; } - FPTemplate(const int& newValue) { value = newValue << upShiftInt; } - FPTemplate(const unsigned int& newValue) { value = newValue << upShiftInt; } - FPTemplate(const long& newValue) { value = newValue << upShiftInt; } - FPTemplate(const unsigned long& newValue) { value = newValue << upShiftInt; } + FPTemplate(const int& newValue) { value = (T)(newValue) << upShiftInt; } + FPTemplate(const unsigned int& newValue) { value = (T)(newValue) << upShiftInt; } + FPTemplate(const long& newValue) { value = (T)(newValue) << upShiftInt; } + FPTemplate(const unsigned long& newValue) { value = (T)(newValue) << upShiftInt; } FPTemplate(const float& newValue) { value = (int)(newValue * (float)upMulInt); } FPTemplate(const double& newValue) { value = (int)(newValue * (double)upMulInt); } void FromFixed(const int& newValue) { value = newValue; } // Accepts an int that is in fixed point format (i.e. shifted) already. @@ -516,7 +516,7 @@ inline FPTemplateType operator*(const FPTemplateType& t1, const FPTemplateType& FPTemplateDeclaration inline FPTemplateType operator*(const FPTemplateType& t1, const int& t2){ FPTemplateType temp; - temp.value = FPTemplateType::FixedMul(t1.value, t2< Date: Sat, 14 Mar 2020 13:13:23 +0100 Subject: [PATCH 2/4] fixed more typecasting errors for long integers --- include/EAStdC/EAFixedPoint.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/EAStdC/EAFixedPoint.h b/include/EAStdC/EAFixedPoint.h index c5b5391..1990706 100644 --- a/include/EAStdC/EAFixedPoint.h +++ b/include/EAStdC/EAFixedPoint.h @@ -156,8 +156,8 @@ struct FPTemplate FPTemplate(const unsigned int& newValue) { value = (T)(newValue) << upShiftInt; } FPTemplate(const long& newValue) { value = (T)(newValue) << upShiftInt; } FPTemplate(const unsigned long& newValue) { value = (T)(newValue) << upShiftInt; } - FPTemplate(const float& newValue) { value = (int)(newValue * (float)upMulInt); } - FPTemplate(const double& newValue) { value = (int)(newValue * (double)upMulInt); } + FPTemplate(const float& newValue) { value = (T)(newValue * (float)upMulInt); } + FPTemplate(const double& newValue) { value = (T)(newValue * (double)upMulInt); } void FromFixed(const int& newValue) { value = newValue; } // Accepts an int that is in fixed point format (i.e. shifted) already. T AsFixed () { return value; } // Allows you to get the fixed point value itself and mess with it as you want. @@ -245,15 +245,15 @@ struct FPTemplate FPTemplate& operator+=(const unsigned int& argValue) { value += (T)(argValue<>=(int numBits) { value >>= numBits; return *this;} - FPTemplate& operator++() { value += 1< Date: Sat, 14 Mar 2020 16:59:49 +0100 Subject: [PATCH 3/4] Add 32:32 fixed point type --- include/EAStdC/EAFixedPoint.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/EAStdC/EAFixedPoint.h b/include/EAStdC/EAFixedPoint.h index 1990706..2c31b17 100644 --- a/include/EAStdC/EAFixedPoint.h +++ b/include/EAStdC/EAFixedPoint.h @@ -992,6 +992,8 @@ typedef FPTemplate UFixed10; typedef FPTemplate SFixed8; // 8:24 fixed point (24 bits of fraction) typedef FPTemplate UFixed8; +typedef FPTemplate SFixed32; // 32:32 fixed point (32 bits of fraction) + /////////////////////////////////////////////////////////////////////////////// #define FPDeclareTemplateSpecializations(TypeDef) \ From b2b13eaa412c26c5a2ee2757044fa5deefd40fd3 Mon Sep 17 00:00:00 2001 From: RicoP Date: Sat, 14 Mar 2020 17:01:17 +0100 Subject: [PATCH 4/4] Add unit test for SFixed32 fixedpoint number --- test/source/TestFixedPoint.cpp | 114 +++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/test/source/TestFixedPoint.cpp b/test/source/TestFixedPoint.cpp index 5aa90fa..b213920 100644 --- a/test/source/TestFixedPoint.cpp +++ b/test/source/TestFixedPoint.cpp @@ -8,6 +8,7 @@ #include #include #include +#include @@ -57,8 +58,43 @@ static bool CompareValues(EA::StdC::SFixed16 a, double b) const volatile uint64_t c = ((uint64_t)a) << 8; return (int32_t)(uint32_t)(c % b); } + + static bool CompareValues(SFixed32 a, double b) { + #define Fixed32ToDouble(a) (((double)a) / (65536.0 * 65536.0)) + + const double c = Fixed32ToDouble(a.AsFixed()); + return (fabs(c - b) < 0.01); + } + template <> + EASTDC_API int64_t FP_PASCAL SFixed32::FixedMul(const int64_t lhs, + const int64_t rhs) { + int128_t lhs128(lhs); + lhs128 *= rhs; + lhs128 >>= 32; + + return lhs128.AsInt64(); + } + + template <> + EASTDC_API int64_t FP_PASCAL SFixed32::FixedDiv(const int64_t lhs, + const int64_t rhs) { + int128_t lhs128(lhs); + lhs128 <<= 32; + lhs128 /= rhs; + + return lhs128.AsInt64(); + } + + template <> + EASTDC_API int64_t FP_PASCAL SFixed32::FixedMod(const int64_t lhs, + const int64_t rhs) { + int128_t c(lhs); + c <<= 32; + return (c % rhs).AsInt64(); + } } } + #endif @@ -224,6 +260,84 @@ int TestFixedPoint() if(!CompareValues(a, 0.77333)) nErrorCount++; } + + //Test SFixed32 + { + SFixed32 a(1), b(2), c(3.f), d(1.0); + double e = 3.2; + float f = 4.5; + int g = 6; + + if (a.AsInt() != 1) nErrorCount++; + if (c.AsUnsignedInt() != 3) nErrorCount++; + if (a.AsLong() != 1) nErrorCount++; + if (c.AsUnsignedLong() != 3) nErrorCount++; + if (!CompareValues((double)a.AsFloat(), 1.0)) nErrorCount++; + if (!CompareValues(c.AsDouble(), 3.0)) nErrorCount++; + + a = b * f; + if (!CompareValues(a, 9.0)) nErrorCount++; + + a = b / d; + if (!CompareValues(a, 2.0)) nErrorCount++; + + a = b + d; + if (!CompareValues(a, 3.0)) nErrorCount++; + + a = (c / e) + b + f; + if (!CompareValues(a, 7.4375)) nErrorCount++; + + a = c / e * (b % g) + f / c; + if (!CompareValues(a, 3.375)) nErrorCount++; + + if (!CompareValues(b, 2.0)) nErrorCount++; + a = g * -c / (b++); + if (!CompareValues(a, -9.0)) nErrorCount++; + if (!CompareValues(b, 3.0)) nErrorCount++; + --b; // Restore it to its original value. + if (!CompareValues(b, 2.0)) nErrorCount++; + + a = sin(d) + pow(b, e) * sqrt(d); + if (!CompareValues(a, 10.031)) nErrorCount++; + + a = log(e) / log(f); + if (!CompareValues(a, 0.77333)) + nErrorCount++; + } + + { + SFixed32 a(16); + + auto expected = a.value << 1; + + a = (a << 1); + + if (!CompareValues(a.value, expected)) nErrorCount++; + } + + // FPTemplate operator>>(int numBits) const + { + SFixed32 a(16); + + auto expected = a.value >> 1; + + a = (a >> 1); + + if (!CompareValues(a.value, expected)) nErrorCount++; + } + + // Reported regression - ensure operator<< and operator>> are + // implemented correctly. + { + SFixed32 a(16); + + auto expected = a.value; + + a = (a << 1); + a = (a >> 1); + + if (!CompareValues(a.value, expected)) nErrorCount++; + } #endif // Test core multiplication/division functions