/* Starshatter: The Open Source Project Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors Copyright (c) 1997-2006, Destroyer Studios LLC. AUTHOR: John DiCamillo OVERVIEW ======== Fixed point number class with 16 bits of fractional precision */ #ifndef Fix_h #define Fix_h // +--------------------------------------------------------------------+ #include "Types.h" // +--------------------------------------------------------------------+ const double fix_sixty_five=65536.0; inline int fast_f2i(double d) { return static_cast(d); } // +--------------------------------------------------------------------+ class fix { public: static const char* TYPENAME() { return "fix"; } enum FixDef { Precision=16, IntMask=0xffff0000, FractMask=0x0000ffff }; static const fix one; static const fix two; static const fix three; static const fix five; static const fix ten; fix() : val(0) { } fix(int n) : val(n<(d * fix_sixty_five)) { } fix(const fix& f) : val(f.val) { } // conversion operators: operator int () const { return (val>>Precision); } operator float () const { return ((float) val) / ((float) fix_sixty_five); } operator double() const { return ((double) val) / fix_sixty_five; } // assignment operators: fix& operator=(const fix& f) { val=f.val; return *this; } fix& operator=(int n) { val=(n<(d * fix_sixty_five); return *this; } // comparison operators: int operator==(const fix& f) const { return val==f.val; } int operator!=(const fix& f) const { return val!=f.val; } int operator<=(const fix& f) const { return val<=f.val; } int operator>=(const fix& f) const { return val>=f.val; } int operator< (const fix& f) const { return val< f.val; } int operator> (const fix& f) const { return val> f.val; } // arithmetic operators: fix operator+(const fix& f) const { fix r; r.val = val+f.val; return r; } fix operator-(const fix& f) const { fix r; r.val = val-f.val; return r; } fix operator*(const fix& f) const { fix r; r.val = (val * f.val) >> Precision; return r; } fix operator/(const fix& f) const { fix r; r.val = (val << Precision) / f.val; return r; } fix& operator+=(const fix& f) { val+=f.val; return *this; } fix& operator-=(const fix& f) { val-=f.val; return *this; } fix& operator*=(const fix& f) { val = (val * f.val) >> Precision; return *this; } fix& operator/=(const fix& f) { val = (val << Precision) / f.val; return *this; } fix operator+(int n) const { fix r; r.val = val+(n<(d); return *this; } fix& operator/=(double d) { val/=static_cast(d); return *this; } // misc. functions: fix truncate() const { fix r; r.val = val&IntMask; return r; } fix fraction() const { fix r; r.val = val-truncate().val; return r; } fix floor() const { fix r; r.val = val&IntMask; return r; } fix ceil() const { fix r; r.val = (val+FractMask)&IntMask; return r; } fix adjust_up() const { fix r; r.val = val+FractMask; return r; } fix adjust_down() const { fix r; r.val = val-FractMask; return r; } fix muldiv(const fix& num, const fix& den) const { return (*this) * num / den; } // data: long val; }; #endif // Fix_h