#ifndef fixed_pt_hpp #define fixed_pt_hpp #include #include //#include // DEBUG namespace cv = boost::constrained_value; template struct rnd { static base_type apply (base_type x) { base_type x1 = x >> (frac_bits-1); if (x1 & 1) return (x1 + 1) >> 1; // overflow? else return (x1 >> 1); } }; template inline int_t nint (flt_t x) { return (x >= 0) ? int_t (x + 0.5) : int_t (x - 0.5); } template inline int_t shift_right (int_t x, int bits) { return x >> bits; } template inline int_t shift_left (int_t x, int bits) { return x << bits; } //! signed fixed pt template, typename round_policy=rnd > struct fixed_pt : boost::ordered_euclidian_ring_operators< fixed_pt, base_type>, boost::ordered_euclidian_ring_operators< fixed_pt, double>, boost::ordered_euclidian_ring_operators< fixed_pt >, boost::shiftable, base_type> { typedef fixed_pt self; static const int total_bits = int_bits + frac_bits; static const base_type max = ~(base_type(-1) << (total_bits-1)); static const base_type min = (base_type(-1) << (total_bits-1)); static const base_type int_max = ~(base_type(-1) << (int_bits-1)); static const base_type int_min = (base_type(-1) << (int_bits-1)); typedef typename cv::bounded_int::type val_t; val_t val; /* explicit */ fixed_pt (base_type x=base_type(0)) : val (x << frac_bits) {}; template /* explicit */ fixed_pt (fixed_pt<_int_bits, _frac_bits, _base_type, _error_policy, _round_policy>const& other) { if (frac_bits > _frac_bits) val = shift_left (base_type (other.val), (frac_bits - _frac_bits)); else val = shift_right (base_type (other.val), (_frac_bits - frac_bits)); } template self& operator= (fixed_pt<_int_bits, _frac_bits, _base_type, _error_policy, _round_policy>const& other) { self tmp (other); *this = tmp; return *this; } /* explicit */ fixed_pt (double x) : val (nint (x * (1 << frac_bits))) {}; //operator base_type() const { return round_policy::apply (val); } self operator+=(self const& x) { val += x.val; return *this; } self operator-=(self const& x) { val -= x.val; return *this; } self operator*=(self const& x) { base_type tmp = (base_type)val * (base_type)x.val; val = tmp >> (frac_bits); return *this; } self operator/=(self const& x) { base_type tmp = (base_type)val / (base_type)x.val; val = tmp << (frac_bits); return *this; } // Don't do these, force conversion to fixed_pt and use above // self operator+=(base_type x) { val += x; return *this; } // self operator-=(base_type x) { val -= x; return *this; } // self operator*=(base_type x) { val *= x; return *this; } // self operator/=(base_type x) { val /= x; return *this; } self operator<<=(int x) { val <<= x; return *this; } self operator>>=(int x) { val >>= x; return *this; } bool operator==(self const& x) const { return val == x.val; } bool operator<(self const& x) const { return val < x.val; } self operator |=(self const& x) { val |= x.val; return *this; } self operator &=(self const& x) { val &= x.val; return *this; } self operator ^=(self const& x) { val ^= x.val; return *this; } // self operator %=(base_type x) { val %= x; return *this; } What should this do? self operator ~() { val = !val; return *this; } // template // self operator+= (fixed_pt<_int_bits, _frac_bits, _base_type, _round_policy>const& other) { // } double as_double() const { return double(val)/(1<