diff --git a/fixed.cpp b/fixed.cpp index 055d47be..609c8aaa 100644 --- a/fixed.cpp +++ b/fixed.cpp @@ -27,8 +27,8 @@ using namespace util; /////////////////////////////////////////////////////////////////////////////// // Constructors -template -fixed::fixed (uint_t val): +template +fixed::fixed (native_t val): m_value (val << E) { static_assert (I > 0, "must use positive integer bits"); @@ -41,56 +41,56 @@ fixed::fixed (uint_t val): /////////////////////////////////////////////////////////////////////////////// // Conversions -template +template double -fixed::to_double (void) const +fixed::to_double (void) const { return static_cast (m_value) / pow (2, E); } //----------------------------------------------------------------------------- -template +template float -fixed::to_float (void) const +fixed::to_float (void) const { return static_cast (m_value) / pow (2, E); } //----------------------------------------------------------------------------- -template -typename fixed::uint_t -fixed::to_integer (void) const +template +typename fixed::native_t +fixed::to_integer (void) const { return m_value >> E; } //----------------------------------------------------------------------------- -template -typename fixed::uint_t -fixed::to_native (void) const +template +typename fixed::native_t +fixed::to_native (void) const { return m_value; } //----------------------------------------------------------------------------- -template -fixed -fixed::from_native (uint_t i) +template +fixed +fixed::from_native (native_t i) { - fixed v; + fixed v; v.m_value = i; return v; } //----------------------------------------------------------------------------- -template -typename fixed::uint_t -fixed::to_integer (uint_t n) +template +typename fixed::native_t +fixed::to_integer (native_t n) { return n >> E; } @@ -98,25 +98,27 @@ fixed::to_integer (uint_t n) /////////////////////////////////////////////////////////////////////////////// // Fixed operators -#define SIMPLE_FIXED_REF(OP) \ -template \ -util::fixed& \ -util::fixed::operator OP (const fixed rhs) \ -{ \ - m_value OP rhs.m_value; \ - return *this; \ +#define SIMPLE_FIXED_REF(OP) \ +template \ +util::fixed& \ +util::fixed::operator OP (const fixed rhs) \ +{ \ + m_value OP rhs.m_value; \ + return *this; \ } SIMPLE_FIXED_REF(-=) SIMPLE_FIXED_REF(+=) -#define SIMPLE_FIXED_LIT(OP) \ -template \ -util::fixed \ -util::fixed::operator OP (const fixed rhs) const \ -{ \ - return fixed {m_value OP rhs.m_value}; \ +#define SIMPLE_FIXED_LIT(OP) \ +template \ +util::fixed \ +util::fixed::operator OP (const fixed rhs) const \ +{ \ + fixed v; \ + v.m_value = m_value OP rhs.m_value; \ + return v; \ } SIMPLE_FIXED_LIT(-) @@ -125,90 +127,44 @@ SIMPLE_FIXED_LIT(+) /////////////////////////////////////////////////////////////////////////////// // Integer operators - -template -fixed& -fixed::operator+= (uint_t val) -{ - m_value += val << E; - return *this; +#define SIMPLE_INTEGER_REF(OP) \ +template \ +fixed& \ +fixed::operator OP (native_t val) \ +{ \ + m_value OP val << E; \ + return *this; \ } +SIMPLE_INTEGER_REF(+=) +SIMPLE_INTEGER_REF(-=) +SIMPLE_INTEGER_REF(*=) +SIMPLE_INTEGER_REF(/=) + //----------------------------------------------------------------------------- -template -fixed& -fixed::operator-= (uint_t val) -{ - m_value -= val << E; - return *this; +#define SIMPLE_INTEGER_LIT(OP) \ +template \ +fixed \ +fixed::operator OP (native_t val) const \ +{ \ + return fixed::from_native (m_value OP val << E); \ } - -//----------------------------------------------------------------------------- -template -fixed& -fixed::operator*= (uint_t val) -{ - m_value *= val; - return *this; -} - - -//----------------------------------------------------------------------------- -template -fixed& -fixed::operator/= (uint_t val) -{ - m_value /= val; - return *this; -} - - -//----------------------------------------------------------------------------- -template -fixed -fixed::operator+ (uint_t val) const -{ - return fixed (m_value + val << E); -} - - -//----------------------------------------------------------------------------- -template -fixed -fixed::operator- (uint_t val) const -{ - return fixed (m_value - val << E); -} - - -//----------------------------------------------------------------------------- -template -fixed -fixed::operator* (uint_t val) const -{ - return fixed (m_value * val); -} - - -//----------------------------------------------------------------------------- -template -fixed -fixed::operator /(uint_t val) const -{ - return fixed (m_value / val); -} +SIMPLE_INTEGER_LIT(+) +SIMPLE_INTEGER_LIT(-) +SIMPLE_INTEGER_LIT(*) +SIMPLE_INTEGER_LIT(/) /////////////////////////////////////////////////////////////////////////////// // logical operators #define LOGIC_OP(OP) \ -template \ +template \ bool \ -util::operator OP (util::fixed a, \ - util::fixed b) \ +util::operator OP (util::fixed a, \ + util::fixed b) \ { \ return a.to_native () OP b.to_native (); \ } @@ -222,9 +178,9 @@ LOGIC_OP(>=) /////////////////////////////////////////////////////////////////////////////// // iostream operators -template +template std::ostream& -util::operator<< (std::ostream &os, fixed v) +util::operator<< (std::ostream &os, fixed v) { return os << v.to_double (); } @@ -233,16 +189,21 @@ util::operator<< (std::ostream &os, fixed v) /////////////////////////////////////////////////////////////////////////////// // Instantiations -#define INSTANTIATE(I,E) \ -template class util::fixed<(I),(E)>; \ -template std::ostream& util::operator<< (std::ostream&, fixed<(I),(E)>); \ -template bool util::operator== (util::fixed<(I),(E)>, util::fixed<(I),(E)>); \ -template bool util::operator!= (util::fixed<(I),(E)>, util::fixed<(I),(E)>); \ -template bool util::operator< (util::fixed<(I),(E)>, util::fixed<(I),(E)>); \ -template bool util::operator<= (util::fixed<(I),(E)>, util::fixed<(I),(E)>); \ -template bool util::operator> (util::fixed<(I),(E)>, util::fixed<(I),(E)>); \ -template bool util::operator>= (util::fixed<(I),(E)>, util::fixed<(I),(E)>); +#define INSTANTIATE(T,I,E) \ +template class util::fixed; \ +template std::ostream& util::operator<< (std::ostream&, fixed); \ +template bool util::operator== (util::fixed, util::fixed); \ +template bool util::operator!= (util::fixed, util::fixed); \ +template bool util::operator< (util::fixed, util::fixed); \ +template bool util::operator<= (util::fixed, util::fixed); \ +template bool util::operator> (util::fixed, util::fixed); \ +template bool util::operator>= (util::fixed, util::fixed); -INSTANTIATE(16,16) -INSTANTIATE(26, 6) -INSTANTIATE(32,32) +template class util::fixed; + +INSTANTIATE(signed,16,16) +INSTANTIATE(signed,26, 6) +INSTANTIATE(signed,32,32) +INSTANTIATE(unsigned,16,16) +INSTANTIATE(unsigned,26, 6) +INSTANTIATE(unsigned,32,32) diff --git a/fixed.hpp b/fixed.hpp index 80f4e1d8..a9136f63 100644 --- a/fixed.hpp +++ b/fixed.hpp @@ -26,61 +26,67 @@ #include namespace util { - template + template class fixed { public: - typedef typename bits_type::uint uint_t; + typedef typename std::conditional< + std::is_signed::value, + typename bits_type::sint, + typename bits_type::uint + >::type native_t; + + typedef native_t integer_t; fixed (double); fixed (float); - fixed (uint_t); + fixed (native_t); - double to_double (void) const; - float to_float (void) const; - uint_t to_integer (void) const; - uint_t to_native (void) const; + double to_double (void) const; + float to_float (void) const; + integer_t to_integer (void) const; + native_t to_native (void) const; - static fixed from_native (uint_t); - static uint_t to_integer (uint_t); + static fixed from_native (native_t); + static integer_t to_integer (native_t); - fixed& operator +=(const fixed); - fixed& operator -=(const fixed); - fixed& operator *=(const fixed); - fixed& operator /=(const fixed); + fixed& operator +=(const fixed); + fixed& operator -=(const fixed); + fixed& operator *=(const fixed); + fixed& operator /=(const fixed); - fixed operator +(const fixed) const; - fixed operator -(const fixed) const; - fixed operator *(const fixed) const; - fixed operator /(const fixed) const; + fixed operator +(const fixed) const; + fixed operator -(const fixed) const; + fixed operator *(const fixed) const; + fixed operator /(const fixed) const; - fixed& operator +=(uint_t); - fixed& operator -=(uint_t); - fixed& operator *=(uint_t); - fixed& operator /=(uint_t); + fixed& operator +=(integer_t); + fixed& operator -=(integer_t); + fixed& operator *=(integer_t); + fixed& operator /=(integer_t); - fixed operator +(uint_t) const; - fixed operator -(uint_t) const; - fixed operator *(uint_t) const; - fixed operator /(uint_t) const; + fixed operator +(integer_t) const; + fixed operator -(integer_t) const; + fixed operator *(integer_t) const; + fixed operator /(integer_t) const; private: fixed () = default; - uint_t m_value; + native_t m_value; }; - template bool operator== (util::fixed, util::fixed); - template bool operator!= (util::fixed, util::fixed); + template bool operator== (util::fixed, util::fixed); + template bool operator!= (util::fixed, util::fixed); - template bool operator< (util::fixed, util::fixed); - template bool operator<= (util::fixed, util::fixed); - template bool operator> (util::fixed, util::fixed); - template bool operator>= (util::fixed, util::fixed); + template bool operator< (util::fixed, util::fixed); + template bool operator<= (util::fixed, util::fixed); + template bool operator> (util::fixed, util::fixed); + template bool operator>= (util::fixed, util::fixed); - template - std::ostream& operator<< (std::ostream&, fixed); + template + std::ostream& operator<< (std::ostream&, fixed); } #endif // __UTIL_FIXED_HPP diff --git a/test/fixed.cpp b/test/fixed.cpp index a21ea649..146a16c5 100644 --- a/test/fixed.cpp +++ b/test/fixed.cpp @@ -2,15 +2,15 @@ #include "debug.hpp" -template +template void test_simple (void) { - using fixed_t = util::fixed; - using uint_t = typename fixed_t::uint_t; + using fixed_t = util::fixed; + using integer_t = typename fixed_t::integer_t; - const fixed_t lo = uint_t{0}; - const fixed_t hi = uint_t{1}; + const fixed_t lo = integer_t{0}; + const fixed_t hi = integer_t{1}; CHECK_EQ (lo, lo); CHECK_EQ (hi, hi); @@ -31,7 +31,11 @@ test_simple (void) int main (void) { - test_simple<16,16> (); - test_simple<26, 6> (); - test_simple<32,32> (); + test_simple (); + test_simple (); + test_simple (); + + test_simple (); + test_simple (); + test_simple (); }