/*********************************** * (C) 2008 by Tomasz bla Fortuna . * License: GPL3+ (See Docs/LICENSE) * * Implementation of signed 16 bit fixed-point numbers ********************/ #include namespace RealType { /* Compile-time power template */ template struct Pow2 { enum {r = 2 * Pow2::r}; }; template<> struct Pow2<0> { enum {r = 1}; }; /* Fixed-point number and operations template. * * T2 should be a type bigger than T * IPart - bits of integer part * FPart - bits of fractional part */ template union Fixed { typedef Fixed MyType; private: T n; struct Parts { T Fraction : FPart; T Integer : IPart; } P; public: /* To create using binary representation use this constructor * and then change n */ Fixed() : n(T()) {}; /* This creates from integers... */ Fixed(T A) : n(A<::r) * Pow2::r)) {} /* Getters */ inline T Integer() { return P.Integer; } inline T Fract() { return P.Fraction * 100 / Pow2::r; } inline T operator*() { return n; } /* Operations */ inline MyType operator+(const MyType &A) { return MyType(n+A.n); } inline MyType operator+(const T A) { return MyType(n + (A << FPart)); } inline MyType operator-(const MyType &A) { return MyType(n-A.n); } inline MyType operator-(const T A) { return MyType(n - (A << FPart)); } inline MyType operator*(const MyType A) { MyType tmp; tmp.n = (((T2) (n * A.n + Pow2::r )) >> FPart); return tmp; } inline MyType operator/(const MyType A) { MyType tmp; tmp.n = ((T2)((n << (FPart+1)) / A.n) + 1 ) / 2; return tmp; } /* 'in-place' */ inline void operator+=(const MyType &A) { n += A.n; } inline void operator+=(const T A) { n += A << FPart; } inline void operator-=(const MyType &A) { n -= A.n; } inline void operator-=(const T A) { n -= A << FPart; } inline void operator*=(const MyType A) { n = (((T2)(n * A.n + Pow2::r )) >> FPart); } inline void operator/=(const MyType A) { n = ((T2)((n << (FPart+1)) / A.n) + 1 ) / 2; } void Debug() { printf("(%d = %hd,%hu)", n, Integer(), Fract()); } }; /* Semi-compatible floating-point class for tests * T - floating point type * T2 - simulated integer /holder/ */ template struct Float { typedef Float MyType; T D; Float() {} Float(T I, T F) : D(I+F) {} Float(T A) : D(A) {} inline operator T&() { return D; } inline operator const T&() const { return D; } // inline T operator*() { return D; } inline T2 Integer() { return (T2)D; } inline T2 Fract() { return (T2)((D - Integer()) * 100000); } /* void Debug() { printf("(FP = %5.10f)", D); } */ }; } /* Create fixed */ /* 16 bit implementation */ //typedef RealType::Fixed Real; /* 32 bit implementation */ //typedef RealType::Fixed Real; /* Floating-point implementation */ typedef RealType::Float Real;