From d05ae67708ec9db54f90ef11292c38ca5c9dba5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20L=C3=BCbke?= Date: Thu, 23 Nov 2023 15:47:38 +0100 Subject: [PATCH] Add simple fixed point type --- include/tug/Datatypes/FixedPoint.hpp | 98 ++++++++++++++++++++++++++++ test/CMakeLists.txt | 3 + test/testFixedPoint.cpp | 35 ++++++++++ 3 files changed, 136 insertions(+) create mode 100644 include/tug/Datatypes/FixedPoint.hpp create mode 100644 test/testFixedPoint.cpp diff --git a/include/tug/Datatypes/FixedPoint.hpp b/include/tug/Datatypes/FixedPoint.hpp new file mode 100644 index 0000000..2ecf0fa --- /dev/null +++ b/include/tug/Datatypes/FixedPoint.hpp @@ -0,0 +1,98 @@ +#ifndef TUG_FIXED_TYPE +#define TUG_FIXED_TYPE + +#include +#include +#include + +namespace tug { + +template +class FixedPoint { +public: + // zero init + constexpr FixedPoint() : _internal_value(0) {} + + // construct a fixed point from value + template + constexpr FixedPoint(T val) + : _internal_value(static_cast(val * IntegerMult)) {} + + // cast a fixed point to a data type + template constexpr operator T() const { + return static_cast(static_cast(_internal_value) / IntegerMult); + } + + // addition + template constexpr FixedPoint operator+(const T &rhs) const { + return FixedPoint(add(this->_internal_value, rhs), {}); + } + + // subtraction + template constexpr FixedPoint operator-(const T &rhs) const { + return FixedPoint(sub(this->_internal_value, rhs), {}); + } + + // multiplication + template constexpr FixedPoint operator*(const T &rhs) const { + return FixedPoint(mul(this->_internal_value, rhs), {}); + } + + // division + template constexpr FixedPoint operator/(const T &rhs) const { + return FixedPoint(div(this->_internal_value, rhs), {}); + } + + // equality + template constexpr bool operator==(const T &rhs) const { + return eq(this->_internal_value, rhs); + } + +private: + struct placeholder {}; + constexpr FixedPoint(BaseType _val, placeholder) : _internal_value(_val) {} + + static constexpr BaseType add(const BaseType _lhs, const FixedPoint _rhs) { + return static_cast(_lhs + _rhs._internal_value); + } + + static constexpr BaseType sub(const BaseType _lhs, const FixedPoint _rhs) { + return static_cast(_lhs - _rhs._internal_value); + } + + static constexpr BaseType mul(const BaseType _lhs, const FixedPoint _rhs) { + return static_cast( + static_cast(_lhs * _rhs._internal_value) / IntegerMult); + } + + static constexpr BaseType div(const BaseType _lhs, const FixedPoint _rhs) { + return static_cast(static_cast(_lhs * IntegerMult) / + _rhs._internal_value); + } + + static constexpr bool eq(const BaseType _lhs, const FixedPoint _rhs) { + return _lhs == _rhs._internal_value; + } + + BaseType _internal_value; +}; + +template +std::ostream &operator<<(std::ostream &os, const FixedPoint &fp) { + os << static_cast(fp); + + return os; +} + +template +using Fixed32 = FixedPoint; + +template +using Fixed16 = FixedPoint; + +template +using Fixed8 = FixedPoint; +} // namespace tug + +#endif // TUG_FIXED_TYPE \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 19c4daf..aaae1d9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -25,3 +25,6 @@ add_custom_target( check COMMAND $ DEPENDS testTug) + +add_executable(fixed_point testFixedPoint.cpp) +target_link_libraries(fixed_point PRIVATE tug) \ No newline at end of file diff --git a/test/testFixedPoint.cpp b/test/testFixedPoint.cpp new file mode 100644 index 0000000..9136b84 --- /dev/null +++ b/test/testFixedPoint.cpp @@ -0,0 +1,35 @@ +#include "tug/Datatypes/FixedPoint.hpp" + +#include +#include + +using namespace tug; + +using FPToTest = Fixed8<5>; + +int main() { + FPToTest with(1.5); + FPToTest without(0.5); + + const int test = 0; + + const FPToTest lol = 0; + + if (lol == test) { + std::cout << "This works\n"; + } + + double operation; + + operation = with + without; + std::cout << "Addition: " << operation << std::endl; + + operation = with - without; + std::cout << "Subtraction: " << operation << std::endl; + + operation = with * without; + std::cout << "Mult: " << operation << std::endl; + + operation = with / without; + std::cout << "Div: " << operation << std::endl; +} \ No newline at end of file