1 /*! ========================================================================
2 ** Extended Template and Library
3 ** Fixed-Point Math Class Implementation
4 ** $Id: _fixed.h,v 1.1.1.1 2005/01/04 01:31:47 darco Exp $
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ** General Public License for more details.
18 ** === N O T E S ===========================================================
20 ** This is an internal header file, included by other ETL headers.
21 ** You should not attempt to use it directly.
23 ** ========================================================================= */
25 /* === S T A R T =========================================================== */
27 #ifndef __ETL__FIXED_H
28 #define __ETL__FIXED_H
30 /* === H E A D E R S ======================================================= */
34 /* === M A C R O S ========================================================= */
36 #ifndef ETL_FIXED_TYPE
37 # define ETL_FIXED_TYPE int
40 #ifndef ETL_FIXED_BITS
41 #define ETL_FIXED_BITS 12
44 #ifndef ETL_FIXED_EPSILON
45 #define ETL_FIXED_EPSILON _EPSILON()
49 #define ETL_ATTRIB_CONST __attribute__ ((const))
50 #define ETL_ATTRIB_PURE __attribute__ ((pure))
51 #define ETL_ATTRIB_INLINE __attribute__ ((always_inline))
53 #define ETL_ATTRIB_CONST
54 #define ETL_ATTRIB_PURE
55 #define ETL_ATTRIB_INLINE
58 /* === C L A S S E S & S T R U C T S ======================================= */
62 // Forward declarations
63 template<typename T, unsigned int FIXED_BITS> class fixed_base;
64 //template<> class fixed_base<char>;
69 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> abs(const _ETL::fixed_base<T,FIXED_BITS>&);
70 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cos(const _ETL::fixed_base<T,FIXED_BITS>&);
71 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cosh(const _ETL::fixed_base<T,FIXED_BITS>&);
72 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> exp(const _ETL::fixed_base<T,FIXED_BITS>&);
73 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log(const _ETL::fixed_base<T,FIXED_BITS>&);
74 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log10(const _ETL::fixed_base<T,FIXED_BITS>&);
75 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, int);
76 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const T&);
77 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&,
78 const _ETL::fixed_base<T,FIXED_BITS>&);
79 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>&);
80 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sin(const _ETL::fixed_base<T,FIXED_BITS>&);
81 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sinh(const _ETL::fixed_base<T,FIXED_BITS>&);
82 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sqrt(const _ETL::fixed_base<T,FIXED_BITS>&);
83 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tan(const _ETL::fixed_base<T,FIXED_BITS>&);
84 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tanh(const _ETL::fixed_base<T,FIXED_BITS>&);
88 /*! ========================================================================
90 ** \brief Fixed-point template base class
92 ** A more detailed description needs to be written.
94 template <class T,unsigned int FIXED_BITS>
102 typedef fixed_base<T,FIXED_BITS> _fixed;
103 typedef fixed_base<T,FIXED_BITS> self_type;
105 inline static bool _TYPE_SMALLER_THAN_INT() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
106 inline static bool _USING_ALL_BITS() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
107 inline static value_type _ONE() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
108 inline static value_type _F_MASK() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
109 inline static float _EPSILON() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
113 fixed_base()ETL_ATTRIB_INLINE;
114 fixed_base(const float &f)ETL_ATTRIB_INLINE;
115 fixed_base(const double &f)ETL_ATTRIB_INLINE;
116 fixed_base(const long double &f)ETL_ATTRIB_INLINE;
117 fixed_base(const int &i)ETL_ATTRIB_INLINE;
118 fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE; //!< Fraction constructor
119 fixed_base(const _fixed &x)ETL_ATTRIB_INLINE;
120 fixed_base(value_type x,raw)ETL_ATTRIB_INLINE;
122 T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
123 const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
125 const _fixed& operator+=(const _fixed &rhs) ETL_ATTRIB_INLINE;
126 const _fixed& operator-=(const _fixed &rhs) ETL_ATTRIB_INLINE;
127 template<typename U> const _fixed& operator*=(const U &rhs) ETL_ATTRIB_INLINE;
128 template<typename U> const _fixed& operator/=(const U &rhs) ETL_ATTRIB_INLINE;
129 const _fixed& operator*=(const _fixed &rhs) ETL_ATTRIB_INLINE;
130 const _fixed& operator/=(const _fixed &rhs) ETL_ATTRIB_INLINE;
131 const _fixed& operator*=(const int &rhs) ETL_ATTRIB_INLINE;
132 const _fixed& operator/=(const int &rhs) ETL_ATTRIB_INLINE;
135 template<typename U> _fixed operator+(const U &rhs)const ETL_ATTRIB_INLINE;
136 template<typename U> _fixed operator-(const U &rhs)const ETL_ATTRIB_INLINE;
137 template<typename U> _fixed operator*(const U &rhs)const ETL_ATTRIB_INLINE;
138 template<typename U> _fixed operator/(const U &rhs)const ETL_ATTRIB_INLINE;
139 _fixed operator+(const _fixed &rhs)const ETL_ATTRIB_INLINE;
140 _fixed operator-(const _fixed &rhs)const ETL_ATTRIB_INLINE;
141 _fixed operator*(const _fixed &rhs)const ETL_ATTRIB_INLINE;
142 _fixed operator/(const _fixed &rhs)const ETL_ATTRIB_INLINE;
143 _fixed operator*(const int &rhs)const ETL_ATTRIB_INLINE;
144 _fixed operator/(const int &rhs)const ETL_ATTRIB_INLINE;
145 _fixed operator*(const float &rhs)const ETL_ATTRIB_INLINE;
146 _fixed operator*(const double &rhs)const ETL_ATTRIB_INLINE;
149 _fixed operator-()const ETL_ATTRIB_INLINE;
152 inline operator float()const ETL_ATTRIB_INLINE;
153 inline operator double()const ETL_ATTRIB_INLINE;
154 inline operator long double()const ETL_ATTRIB_INLINE;
155 inline operator int()const ETL_ATTRIB_INLINE;
156 inline operator bool()const ETL_ATTRIB_INLINE;
162 bool operator==(const _fixed &rhs)const { return data()==rhs.data(); }
163 bool operator!=(const _fixed &rhs)const { return data()!=rhs.data(); }
164 bool operator<(const _fixed &rhs)const { return data()<rhs.data(); }
165 bool operator>(const _fixed &rhs)const { return data()>rhs.data(); }
166 bool operator<=(const _fixed &rhs)const { return data()<=rhs.data(); }
167 bool operator>=(const _fixed &rhs)const { return data()>=rhs.data(); }
171 template <class T,unsigned int FIXED_BITS>
172 fixed_base<T,FIXED_BITS>::fixed_base()
175 template <class T,unsigned int FIXED_BITS>
176 fixed_base<T,FIXED_BITS>::fixed_base(const _fixed &x):_data(x._data)
179 template <class T,unsigned int FIXED_BITS>
180 fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()/*+0.5f*/))
183 template <class T,unsigned int FIXED_BITS>
184 fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()/*+0.5*/))
187 template <class T,unsigned int FIXED_BITS>
188 fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()/*+0.5*/))
191 template <class T,unsigned int FIXED_BITS>
192 fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
195 template <class T,unsigned int FIXED_BITS>
196 fixed_base<T,FIXED_BITS>::fixed_base(value_type x,raw):_data(x) { }
198 template <class T,unsigned int FIXED_BITS>
199 fixed_base<T,FIXED_BITS>::fixed_base(const int &n,const int &d):_data((n<<FIXED_BITS)/d) { }
203 template <class T,unsigned int FIXED_BITS> inline bool
204 fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT()
206 return sizeof(T)<sizeof(int);
209 template <class T,unsigned int FIXED_BITS> inline bool
210 fixed_base<T,FIXED_BITS>::_USING_ALL_BITS()
212 return sizeof(T)*8==FIXED_BITS;
215 template <class T,unsigned int FIXED_BITS> inline T
216 fixed_base<T,FIXED_BITS>::_ONE()
218 return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
221 template <class T,unsigned int FIXED_BITS> inline T
222 fixed_base<T,FIXED_BITS>::_F_MASK()
224 return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
227 template <class T,unsigned int FIXED_BITS> inline float
228 fixed_base<T,FIXED_BITS>::_EPSILON()
230 return 1.0f/((float)_ONE()*2);
234 template <class T,unsigned int FIXED_BITS>T &
235 fixed_base<T,FIXED_BITS>::data()
240 template <class T,unsigned int FIXED_BITS>const T &
241 fixed_base<T,FIXED_BITS>::data()const
247 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
248 fixed_base<T,FIXED_BITS>::operator+=(const fixed_base<T,FIXED_BITS> &rhs)
255 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
256 fixed_base<T,FIXED_BITS>::operator-=(const fixed_base<T,FIXED_BITS> &rhs)
263 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
264 fixed_base<T,FIXED_BITS>::operator*=(const fixed_base<T,FIXED_BITS> &rhs)
266 if(_TYPE_SMALLER_THAN_INT())
267 _data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
278 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
279 fixed_base<T,FIXED_BITS>::operator/=(const fixed_base<T,FIXED_BITS> &rhs)
281 if(_TYPE_SMALLER_THAN_INT())
282 _data=static_cast<T>((int)_data/(int)rhs._data<<FIXED_BITS);
291 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
292 fixed_base<T,FIXED_BITS>::operator*=(const U &rhs)
294 return operator*=(fixed_base<T,FIXED_BITS>(rhs));
297 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
298 fixed_base<T,FIXED_BITS>::operator/=(const U &rhs)
300 return operator/=(fixed_base<T,FIXED_BITS>(rhs));
304 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
305 fixed_base<T,FIXED_BITS>::operator*=(const int &rhs)
307 _data*=rhs; return *this;
311 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
312 fixed_base<T,FIXED_BITS>::operator/=(const int &rhs)
314 _data/=rhs; return *this;
324 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
325 fixed_base<T,FIXED_BITS>::operator+(const fixed_base<T,FIXED_BITS> &rhs)const
328 ret._data=_data+rhs._data;
333 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
334 fixed_base<T,FIXED_BITS>::operator-(const fixed_base<T,FIXED_BITS> &rhs)const
337 ret._data=_data-rhs._data;
342 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
343 fixed_base<T,FIXED_BITS>::operator*(const fixed_base<T,FIXED_BITS> &rhs)const
346 ret._data=((_data*rhs._data)>>FIXED_BITS);
348 //return reinterpret_cast<_fixed>((_data*rhs._data)>>FIXED_BITS);
352 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
353 fixed_base<T,FIXED_BITS>::operator/(const fixed_base<T,FIXED_BITS> &rhs)const
356 ret._data=((_data/rhs._data)<<FIXED_BITS);
358 //return reinterpret_cast<_fixed>((_data/rhs._data)<<FIXED_BITS);
362 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
363 fixed_base<T,FIXED_BITS>::operator+(const U &rhs) const
365 return operator+(fixed_base<T,FIXED_BITS>(rhs));
369 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
370 fixed_base<T,FIXED_BITS>::operator-(const U &rhs) const
372 return operator-(fixed_base<T,FIXED_BITS>(rhs));
376 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
377 fixed_base<T,FIXED_BITS>::operator*(const U &rhs) const
379 return operator*(fixed_base<T,FIXED_BITS>(rhs));
383 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
384 fixed_base<T,FIXED_BITS>::operator/(const U &rhs) const
386 return operator/(fixed_base<T,FIXED_BITS>(rhs));
390 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
391 fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const
396 //return reinterpret_cast<_fixed>(_data*rhs);
400 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
401 fixed_base<T,FIXED_BITS>::operator*(const float &rhs)const
403 return (*this)*_fixed(rhs);
407 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
408 fixed_base<T,FIXED_BITS>::operator*(const double &rhs)const
410 return (*this)*_fixed(rhs);
415 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
416 fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const
421 //return reinterpret_cast<_fixed>(_data/rhs);
425 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
426 operator*(const float& lhs, const fixed_base<T,FIXED_BITS> &rhs)
432 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
433 operator*(const double& lhs, const fixed_base<T,FIXED_BITS> &rhs)
444 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
445 fixed_base<T,FIXED_BITS>::operator-()const
447 _fixed ret; ret._data=-_data; return ret;
451 template <class T,unsigned int FIXED_BITS>
452 fixed_base<T,FIXED_BITS>::operator float()const
454 return static_cast<float>(_data)/static_cast<float>(_ONE());
457 template <class T,unsigned int FIXED_BITS>
458 fixed_base<T,FIXED_BITS>::operator double()const
460 return static_cast<double>(_data)/static_cast<double>(_ONE());
463 template <class T,unsigned int FIXED_BITS>
464 fixed_base<T,FIXED_BITS>::operator long double()const
466 return static_cast<long double>(_data)/static_cast<long double>(_ONE());
469 template <class T,unsigned int FIXED_BITS>
470 fixed_base<T,FIXED_BITS>::operator int()const
472 return static_cast<int>(_data>>FIXED_BITS);
475 template <class T,unsigned int FIXED_BITS>
476 fixed_base<T,FIXED_BITS>::operator bool()const
478 return static_cast<bool>(_data);
482 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
483 fixed_base<T,FIXED_BITS>::floor()const
486 ret._data&=~_F_MASK();
490 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
491 fixed_base<T,FIXED_BITS>::ceil()const
494 if(ret._data&_F_MASK())
495 ret._data=(ret._data&~_F_MASK()) + _ONE();
497 ret._data&=~_F_MASK();
501 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
502 fixed_base<T,FIXED_BITS>::round()const
505 ret._data+=_ONE()>>1;
506 ret._data&=~_F_MASK();
535 typedef fixed_base<ETL_FIXED_TYPE,ETL_FIXED_BITS> fixed;
541 template <class T,unsigned int FIXED_BITS>
542 inline _ETL::fixed_base<T,FIXED_BITS>
543 ceil(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
544 { return rhs.ceil(); }
546 template <class T,unsigned int FIXED_BITS>
547 _ETL::fixed_base<T,FIXED_BITS>
548 floor(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
549 { return rhs.floor(); }
551 template <class T,unsigned int FIXED_BITS>
552 _ETL::fixed_base<T,FIXED_BITS>
553 round(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
554 { return rhs.round(); }
556 template <class T,unsigned int FIXED_BITS>
557 _ETL::fixed_base<T,FIXED_BITS>
558 abs(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
559 { return rhs<_ETL::fixed_base<T,FIXED_BITS>(0)?-rhs:rhs; }
564 template <class T,unsigned int FIXED_BITS, typename U> bool
565 operator==(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
566 { return lhs.data()==rhs.data(); }
568 template <class T,unsigned int FIXED_BITS, typename U> bool
569 operator!=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
570 { return lhs.data()!=rhs.data(); }
572 template <class T,unsigned int FIXED_BITS, typename U> bool
573 operator>(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
574 { return lhs.data()>rhs.data(); }
576 template <class T,unsigned int FIXED_BITS, typename U> bool
577 operator<(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
578 { return lhs.data()<rhs.data(); }
580 template <class T,unsigned int FIXED_BITS, typename U> bool
581 operator>=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
582 { return lhs.data()>=rhs.data(); }
584 template <class T,unsigned int FIXED_BITS, typename U> bool
585 operator<=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
586 { return lhs.data()<=rhs.data(); }
590 #if defined(__GNUC__) && __GNUC__ == 3
591 template <class T,unsigned int FIXED_BITS, typename U> U
592 operator*(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
593 { return a*static_cast<double>(b); }
595 template <class T,unsigned int FIXED_BITS, typename U> U
596 operator/(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
597 { return a/static_cast<double>(b); }
599 template <class T,unsigned int FIXED_BITS, typename U> U
600 operator+(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
601 { return a+static_cast<double>(b); }
603 template <class T,unsigned int FIXED_BITS, typename U> U
604 operator-(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
605 { return a-static_cast<double>(b); }
610 operator*=(float &a,const _ETL::fixed &b)
611 { a*=(float)b; return a; }
614 operator/=(float &a,const _ETL::fixed &b)
615 { a/=(float)b; return a; }
618 operator-=(float &a,const _ETL::fixed &b)
619 { a-=(float)b; return a; }
622 operator+=(float &a,const _ETL::fixed &b)
623 { a+=(float)b; return a; }
627 /* === E N D =============================================================== */