/*! ========================================================================
** Extended Template and Library
** Fixed-Point Math Class Implementation
-** $Id: _fixed.h,v 1.1.1.1 2005/01/04 01:31:47 darco Exp $
+** $Id$
**
** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+** Copyright (c) 2007 Chris Moore
**
** This package is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
/* === M A C R O S ========================================================= */
+// the "+0.5" code was commented out - maybe to make thing run faster?
+// it can be re-enabled by uncommenting this next line:
+// #define ROUND_TO_NEAREST_INTEGER
+
#ifndef ETL_FIXED_TYPE
# define ETL_FIXED_TYPE int
#endif
template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log10(const _ETL::fixed_base<T,FIXED_BITS>&);
template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, int);
template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const T&);
-template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&,
+template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&,
const _ETL::fixed_base<T,FIXED_BITS>&);
template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const _ETL::fixed_base<T,FIXED_BITS>&);
template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sin(const _ETL::fixed_base<T,FIXED_BITS>&);
typedef T value_type;
private:
T _data;
-
+
typedef fixed_base<T,FIXED_BITS> _fixed;
typedef fixed_base<T,FIXED_BITS> self_type;
class raw { };
public:
fixed_base()ETL_ATTRIB_INLINE;
- fixed_base(const _fixed &x)ETL_ATTRIB_INLINE;
fixed_base(const float &f)ETL_ATTRIB_INLINE;
fixed_base(const double &f)ETL_ATTRIB_INLINE;
fixed_base(const long double &f)ETL_ATTRIB_INLINE;
fixed_base(const int &i)ETL_ATTRIB_INLINE;
fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE; //!< Fraction constructor
+ fixed_base(const _fixed &x)ETL_ATTRIB_INLINE;
fixed_base(value_type x,raw)ETL_ATTRIB_INLINE;
- T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
+ T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
const _fixed& operator+=(const _fixed &rhs) ETL_ATTRIB_INLINE;
_fixed operator/(const _fixed &rhs)const ETL_ATTRIB_INLINE;
_fixed operator*(const int &rhs)const ETL_ATTRIB_INLINE;
_fixed operator/(const int &rhs)const ETL_ATTRIB_INLINE;
-
+ _fixed operator*(const float &rhs)const ETL_ATTRIB_INLINE;
+ _fixed operator*(const double &rhs)const ETL_ATTRIB_INLINE;
+
// Negation Operator
_fixed operator-()const ETL_ATTRIB_INLINE;
_fixed floor()const;
_fixed ceil()const;
_fixed round()const;
-
+
bool operator==(const _fixed &rhs)const { return data()==rhs.data(); }
bool operator!=(const _fixed &rhs)const { return data()!=rhs.data(); }
bool operator<(const _fixed &rhs)const { return data()<rhs.data(); }
template <class T,unsigned int FIXED_BITS>
fixed_base<T,FIXED_BITS>::fixed_base()
-{}
+{}
template <class T,unsigned int FIXED_BITS>
fixed_base<T,FIXED_BITS>::fixed_base(const _fixed &x):_data(x._data)
{}
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()+0.5f))
-{}
+fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()
+#ifdef ROUND_TO_NEAREST_INTEGER
+ +0.5f
+#endif
+ )) {}
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()+0.5))
-{}
+fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()
+#ifdef ROUND_TO_NEAREST_INTEGER
+ +0.5
+#endif
+ )) {}
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()+0.5))
-{}
+fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()
+#ifdef ROUND_TO_NEAREST_INTEGER
+ +0.5
+#endif
+ )) {}
template <class T,unsigned int FIXED_BITS>
fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
template <class T,unsigned int FIXED_BITS>
fixed_base<T,FIXED_BITS>::fixed_base(const int &n,const int &d):_data((n<<FIXED_BITS)/d) { }
-
-
+
+
template <class T,unsigned int FIXED_BITS> inline bool
-fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT()
+fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT()
{
return sizeof(T)<sizeof(int);
-}
+}
template <class T,unsigned int FIXED_BITS> inline bool
-fixed_base<T,FIXED_BITS>::_USING_ALL_BITS()
+fixed_base<T,FIXED_BITS>::_USING_ALL_BITS()
{
return sizeof(T)*8==FIXED_BITS;
}
template <class T,unsigned int FIXED_BITS> inline T
-fixed_base<T,FIXED_BITS>::_ONE()
+fixed_base<T,FIXED_BITS>::_ONE()
{
return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
}
template <class T,unsigned int FIXED_BITS> inline T
-fixed_base<T,FIXED_BITS>::_F_MASK()
+fixed_base<T,FIXED_BITS>::_F_MASK()
{
return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
}
template <class T,unsigned int FIXED_BITS> inline float
-fixed_base<T,FIXED_BITS>::_EPSILON()
+fixed_base<T,FIXED_BITS>::_EPSILON()
{
return 1.0f/((float)_ONE()*2);
}
template <class T,unsigned int FIXED_BITS>T &
-fixed_base<T,FIXED_BITS>::data()
+fixed_base<T,FIXED_BITS>::data()
{
return _data;
}
template <class T,unsigned int FIXED_BITS>const T &
-fixed_base<T,FIXED_BITS>::data()const
+fixed_base<T,FIXED_BITS>::data()const
{
return _data;
}
//! fixed+=fixed
template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator+=(const fixed_base<T,FIXED_BITS> &rhs)
+fixed_base<T,FIXED_BITS>::operator+=(const _fixed &rhs)
{
_data+=rhs._data;
return *this;
//! fixed-=fixed
template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator-=(const fixed_base<T,FIXED_BITS> &rhs)
+fixed_base<T,FIXED_BITS>::operator-=(const _fixed &rhs)
{
_data-=rhs._data;
return *this;
//! fixed*=fixed
template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator*=(const fixed_base<T,FIXED_BITS> &rhs)
+fixed_base<T,FIXED_BITS>::operator*=(const _fixed &rhs)
{
if(_TYPE_SMALLER_THAN_INT())
_data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
_data*=rhs._data;
_data>>=FIXED_BITS;
}
-
+
return *this;
}
//! fixed/=fixed
template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator/=(const fixed_base<T,FIXED_BITS> &rhs)
+fixed_base<T,FIXED_BITS>::operator/=(const _fixed &rhs)
{
if(_TYPE_SMALLER_THAN_INT())
_data=static_cast<T>((int)_data/(int)rhs._data<<FIXED_BITS);
}
template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator*=(const U &rhs)
+fixed_base<T,FIXED_BITS>::operator*=(const U &rhs)
{
return operator*=(fixed_base<T,FIXED_BITS>(rhs));
}
template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator/=(const U &rhs)
+fixed_base<T,FIXED_BITS>::operator/=(const U &rhs)
{
return operator/=(fixed_base<T,FIXED_BITS>(rhs));
}
//! fixed*=int
template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator*=(const int &rhs)
+fixed_base<T,FIXED_BITS>::operator*=(const int &rhs)
{
_data*=rhs; return *this;
}
//! fixed/=int
template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
-fixed_base<T,FIXED_BITS>::operator/=(const int &rhs)
+fixed_base<T,FIXED_BITS>::operator/=(const int &rhs)
{
_data/=rhs; return *this;
}
//! fixed + fixed
template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator+(const fixed_base<T,FIXED_BITS> &rhs)const
+fixed_base<T,FIXED_BITS>::operator+(const _fixed &rhs)const
{
_fixed ret;
ret._data=_data+rhs._data;
//! fixed - fixed
template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator-(const fixed_base<T,FIXED_BITS> &rhs)const
+fixed_base<T,FIXED_BITS>::operator-(const _fixed &rhs)const
{
_fixed ret;
ret._data=_data-rhs._data;
//! fixed * fixed
template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator*(const fixed_base<T,FIXED_BITS> &rhs)const
+fixed_base<T,FIXED_BITS>::operator*(const _fixed &rhs)const
{
_fixed ret;
ret._data=((_data*rhs._data)>>FIXED_BITS);
//! fixed / fixed
template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator/(const fixed_base<T,FIXED_BITS> &rhs)const
+fixed_base<T,FIXED_BITS>::operator/(const _fixed &rhs)const
{
_fixed ret;
ret._data=((_data/rhs._data)<<FIXED_BITS);
//! fixed * int
template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const
+fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const
{
_fixed ret;
ret._data=_data*rhs;
//return reinterpret_cast<_fixed>(_data*rhs);
}
+//! fixed * float
+template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
+fixed_base<T,FIXED_BITS>::operator*(const float &rhs)const
+{
+ return (*this)*_fixed(rhs);
+}
+
+//! fixed * double
+template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
+fixed_base<T,FIXED_BITS>::operator*(const double &rhs)const
+{
+ return (*this)*_fixed(rhs);
+}
+
+
//! fixed / int
template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const
+fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const
{
_fixed ret;
ret._data=_data/rhs;
//return reinterpret_cast<_fixed>(_data/rhs);
}
+//! float * fixed
+template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
+operator*(const float& lhs, const fixed_base<T,FIXED_BITS> &rhs)
+{
+ return rhs*lhs;
+}
+//! double * fixed
+template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
+operator*(const double& lhs, const fixed_base<T,FIXED_BITS> &rhs)
+{
+ return rhs*lhs;
+}
// Negation Operator
template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator-()const
+fixed_base<T,FIXED_BITS>::operator-()const
{
_fixed ret; ret._data=-_data; return ret;
}
// Casting Operators
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator float()const
+fixed_base<T,FIXED_BITS>::operator float()const
{
return static_cast<float>(_data)/static_cast<float>(_ONE());
-}
+}
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator double()const
+fixed_base<T,FIXED_BITS>::operator double()const
{
return static_cast<double>(_data)/static_cast<double>(_ONE());
-}
+}
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator long double()const
+fixed_base<T,FIXED_BITS>::operator long double()const
{
return static_cast<long double>(_data)/static_cast<long double>(_ONE());
-}
+}
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator int()const
+fixed_base<T,FIXED_BITS>::operator int()const
{
return static_cast<int>(_data>>FIXED_BITS);
}
template <class T,unsigned int FIXED_BITS>
-fixed_base<T,FIXED_BITS>::operator bool()const
+fixed_base<T,FIXED_BITS>::operator bool()const
{
return static_cast<bool>(_data);
}