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 _fixed &x)ETL_ATTRIB_INLINE;
115 fixed_base(const float &f)ETL_ATTRIB_INLINE;
116 fixed_base(const double &f)ETL_ATTRIB_INLINE;
117 fixed_base(const long double &f)ETL_ATTRIB_INLINE;
118 fixed_base(const int &i)ETL_ATTRIB_INLINE;
119 fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE; //!< Fraction constructor
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;
147 _fixed operator-()const ETL_ATTRIB_INLINE;
150 inline operator float()const ETL_ATTRIB_INLINE;
151 inline operator double()const ETL_ATTRIB_INLINE;
152 inline operator long double()const ETL_ATTRIB_INLINE;
153 inline operator int()const ETL_ATTRIB_INLINE;
154 inline operator bool()const ETL_ATTRIB_INLINE;
160 bool operator==(const _fixed &rhs)const { return data()==rhs.data(); }
161 bool operator!=(const _fixed &rhs)const { return data()!=rhs.data(); }
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(); }
169 template <class T,unsigned int FIXED_BITS>
170 fixed_base<T,FIXED_BITS>::fixed_base()
173 template <class T,unsigned int FIXED_BITS>
174 fixed_base<T,FIXED_BITS>::fixed_base(const _fixed &x):_data(x._data)
177 template <class T,unsigned int FIXED_BITS>
178 fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()+0.5f))
181 template <class T,unsigned int FIXED_BITS>
182 fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()+0.5))
185 template <class T,unsigned int FIXED_BITS>
186 fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()+0.5))
189 template <class T,unsigned int FIXED_BITS>
190 fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
193 template <class T,unsigned int FIXED_BITS>
194 fixed_base<T,FIXED_BITS>::fixed_base(value_type x,raw):_data(x) { }
196 template <class T,unsigned int FIXED_BITS>
197 fixed_base<T,FIXED_BITS>::fixed_base(const int &n,const int &d):_data((n<<FIXED_BITS)/d) { }
201 template <class T,unsigned int FIXED_BITS> inline bool
202 fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT()
204 return sizeof(T)<sizeof(int);
207 template <class T,unsigned int FIXED_BITS> inline bool
208 fixed_base<T,FIXED_BITS>::_USING_ALL_BITS()
210 return sizeof(T)*8==FIXED_BITS;
213 template <class T,unsigned int FIXED_BITS> inline T
214 fixed_base<T,FIXED_BITS>::_ONE()
216 return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
219 template <class T,unsigned int FIXED_BITS> inline T
220 fixed_base<T,FIXED_BITS>::_F_MASK()
222 return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
225 template <class T,unsigned int FIXED_BITS> inline float
226 fixed_base<T,FIXED_BITS>::_EPSILON()
228 return 1.0f/((float)_ONE()*2);
232 template <class T,unsigned int FIXED_BITS>T &
233 fixed_base<T,FIXED_BITS>::data()
238 template <class T,unsigned int FIXED_BITS>const T &
239 fixed_base<T,FIXED_BITS>::data()const
245 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
246 fixed_base<T,FIXED_BITS>::operator+=(const fixed_base<T,FIXED_BITS> &rhs)
253 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
254 fixed_base<T,FIXED_BITS>::operator-=(const fixed_base<T,FIXED_BITS> &rhs)
261 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
262 fixed_base<T,FIXED_BITS>::operator*=(const fixed_base<T,FIXED_BITS> &rhs)
264 if(_TYPE_SMALLER_THAN_INT())
265 _data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
276 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
277 fixed_base<T,FIXED_BITS>::operator/=(const fixed_base<T,FIXED_BITS> &rhs)
279 if(_TYPE_SMALLER_THAN_INT())
280 _data=static_cast<T>((int)_data/(int)rhs._data<<FIXED_BITS);
289 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
290 fixed_base<T,FIXED_BITS>::operator*=(const U &rhs)
292 return operator*=(fixed_base<T,FIXED_BITS>(rhs));
295 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
296 fixed_base<T,FIXED_BITS>::operator/=(const U &rhs)
298 return operator/=(fixed_base<T,FIXED_BITS>(rhs));
302 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
303 fixed_base<T,FIXED_BITS>::operator*=(const int &rhs)
305 _data*=rhs; return *this;
309 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
310 fixed_base<T,FIXED_BITS>::operator/=(const int &rhs)
312 _data/=rhs; return *this;
322 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
323 fixed_base<T,FIXED_BITS>::operator+(const fixed_base<T,FIXED_BITS> &rhs)const
326 ret._data=_data+rhs._data;
331 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
332 fixed_base<T,FIXED_BITS>::operator-(const fixed_base<T,FIXED_BITS> &rhs)const
335 ret._data=_data-rhs._data;
340 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
341 fixed_base<T,FIXED_BITS>::operator*(const fixed_base<T,FIXED_BITS> &rhs)const
344 ret._data=((_data*rhs._data)>>FIXED_BITS);
346 //return reinterpret_cast<_fixed>((_data*rhs._data)>>FIXED_BITS);
350 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
351 fixed_base<T,FIXED_BITS>::operator/(const fixed_base<T,FIXED_BITS> &rhs)const
354 ret._data=((_data/rhs._data)<<FIXED_BITS);
356 //return reinterpret_cast<_fixed>((_data/rhs._data)<<FIXED_BITS);
360 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
361 fixed_base<T,FIXED_BITS>::operator+(const U &rhs) const
363 return operator+(fixed_base<T,FIXED_BITS>(rhs));
367 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
368 fixed_base<T,FIXED_BITS>::operator-(const U &rhs) const
370 return operator-(fixed_base<T,FIXED_BITS>(rhs));
374 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
375 fixed_base<T,FIXED_BITS>::operator*(const U &rhs) const
377 return operator*(fixed_base<T,FIXED_BITS>(rhs));
381 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
382 fixed_base<T,FIXED_BITS>::operator/(const U &rhs) const
384 return operator/(fixed_base<T,FIXED_BITS>(rhs));
388 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
389 fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const
394 //return reinterpret_cast<_fixed>(_data*rhs);
398 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
399 fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const
404 //return reinterpret_cast<_fixed>(_data/rhs);
415 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
416 fixed_base<T,FIXED_BITS>::operator-()const
418 _fixed ret; ret._data=-_data; return ret;
422 template <class T,unsigned int FIXED_BITS>
423 fixed_base<T,FIXED_BITS>::operator float()const
425 return static_cast<float>(_data)/static_cast<float>(_ONE());
428 template <class T,unsigned int FIXED_BITS>
429 fixed_base<T,FIXED_BITS>::operator double()const
431 return static_cast<double>(_data)/static_cast<double>(_ONE());
434 template <class T,unsigned int FIXED_BITS>
435 fixed_base<T,FIXED_BITS>::operator long double()const
437 return static_cast<long double>(_data)/static_cast<long double>(_ONE());
440 template <class T,unsigned int FIXED_BITS>
441 fixed_base<T,FIXED_BITS>::operator int()const
443 return static_cast<int>(_data>>FIXED_BITS);
446 template <class T,unsigned int FIXED_BITS>
447 fixed_base<T,FIXED_BITS>::operator bool()const
449 return static_cast<bool>(_data);
453 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
454 fixed_base<T,FIXED_BITS>::floor()const
457 ret._data&=~_F_MASK();
461 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
462 fixed_base<T,FIXED_BITS>::ceil()const
465 if(ret._data&_F_MASK())
466 ret._data=(ret._data&~_F_MASK()) + _ONE();
468 ret._data&=~_F_MASK();
472 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
473 fixed_base<T,FIXED_BITS>::round()const
476 ret._data+=_ONE()>>1;
477 ret._data&=~_F_MASK();
506 typedef fixed_base<ETL_FIXED_TYPE,ETL_FIXED_BITS> fixed;
512 template <class T,unsigned int FIXED_BITS>
513 inline _ETL::fixed_base<T,FIXED_BITS>
514 ceil(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
515 { return rhs.ceil(); }
517 template <class T,unsigned int FIXED_BITS>
518 _ETL::fixed_base<T,FIXED_BITS>
519 floor(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
520 { return rhs.floor(); }
522 template <class T,unsigned int FIXED_BITS>
523 _ETL::fixed_base<T,FIXED_BITS>
524 round(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
525 { return rhs.round(); }
527 template <class T,unsigned int FIXED_BITS>
528 _ETL::fixed_base<T,FIXED_BITS>
529 abs(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
530 { return rhs<_ETL::fixed_base<T,FIXED_BITS>(0)?-rhs:rhs; }
535 template <class T,unsigned int FIXED_BITS, typename U> bool
536 operator==(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
537 { return lhs.data()==rhs.data(); }
539 template <class T,unsigned int FIXED_BITS, typename U> bool
540 operator!=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
541 { return lhs.data()!=rhs.data(); }
543 template <class T,unsigned int FIXED_BITS, typename U> bool
544 operator>(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
545 { return lhs.data()>rhs.data(); }
547 template <class T,unsigned int FIXED_BITS, typename U> bool
548 operator<(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
549 { return lhs.data()<rhs.data(); }
551 template <class T,unsigned int FIXED_BITS, typename U> bool
552 operator>=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
553 { return lhs.data()>=rhs.data(); }
555 template <class T,unsigned int FIXED_BITS, typename U> bool
556 operator<=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
557 { return lhs.data()<=rhs.data(); }
561 #if defined(__GNUC__) && __GNUC__ == 3
562 template <class T,unsigned int FIXED_BITS, typename U> U
563 operator*(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
564 { return a*static_cast<double>(b); }
566 template <class T,unsigned int FIXED_BITS, typename U> U
567 operator/(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
568 { return a/static_cast<double>(b); }
570 template <class T,unsigned int FIXED_BITS, typename U> U
571 operator+(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
572 { return a+static_cast<double>(b); }
574 template <class T,unsigned int FIXED_BITS, typename U> U
575 operator-(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
576 { return a-static_cast<double>(b); }
581 operator*=(float &a,const _ETL::fixed &b)
582 { a*=(float)b; return a; }
585 operator/=(float &a,const _ETL::fixed &b)
586 { a/=(float)b; return a; }
589 operator-=(float &a,const _ETL::fixed &b)
590 { a-=(float)b; return a; }
593 operator+=(float &a,const _ETL::fixed &b)
594 { a+=(float)b; return a; }
598 /* === E N D =============================================================== */