00001
00026
00027
00028 #ifndef __ETL__FIXED_H
00029 #define __ETL__FIXED_H
00030
00031
00032
00033 #include <cmath>
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef ETL_FIXED_TYPE
00042 # define ETL_FIXED_TYPE int
00043 #endif
00044
00045 #ifndef ETL_FIXED_BITS
00046 #define ETL_FIXED_BITS 12
00047 #endif
00048
00049 #ifndef ETL_FIXED_EPSILON
00050 #define ETL_FIXED_EPSILON _EPSILON()
00051 #endif
00052
00053 #ifdef __GNUC___
00054 #define ETL_ATTRIB_CONST __attribute__ ((const))
00055 #define ETL_ATTRIB_PURE __attribute__ ((pure))
00056 #define ETL_ATTRIB_INLINE __attribute__ ((always_inline))
00057 #else
00058 #define ETL_ATTRIB_CONST
00059 #define ETL_ATTRIB_PURE
00060 #define ETL_ATTRIB_INLINE
00061 #endif
00062
00063
00064
00065 _ETL_BEGIN_NAMESPACE
00066
00067
00068 template<typename T, unsigned int FIXED_BITS> class fixed_base;
00069
00070
00071 _ETL_END_NAMESPACE
00072
00073 _STD_BEGIN_NAMESPACE
00074 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> abs(const _ETL::fixed_base<T,FIXED_BITS>&);
00075 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cos(const _ETL::fixed_base<T,FIXED_BITS>&);
00076 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cosh(const _ETL::fixed_base<T,FIXED_BITS>&);
00077 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> exp(const _ETL::fixed_base<T,FIXED_BITS>&);
00078 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log(const _ETL::fixed_base<T,FIXED_BITS>&);
00079 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log10(const _ETL::fixed_base<T,FIXED_BITS>&);
00080 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, int);
00081 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const T&);
00082 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&,
00083 const _ETL::fixed_base<T,FIXED_BITS>&);
00084 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>&);
00085 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sin(const _ETL::fixed_base<T,FIXED_BITS>&);
00086 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sinh(const _ETL::fixed_base<T,FIXED_BITS>&);
00087 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sqrt(const _ETL::fixed_base<T,FIXED_BITS>&);
00088 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tan(const _ETL::fixed_base<T,FIXED_BITS>&);
00089 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tanh(const _ETL::fixed_base<T,FIXED_BITS>&);
00090 _STD_END_NAMESPACE
00091 _ETL_BEGIN_NAMESPACE
00092
00099 template <class T,unsigned int FIXED_BITS>
00100 class fixed_base
00101 {
00102 public:
00103 typedef T value_type;
00104 private:
00105 T _data;
00106
00107 typedef fixed_base<T,FIXED_BITS> _fixed;
00108 typedef fixed_base<T,FIXED_BITS> self_type;
00109
00110 inline static bool _TYPE_SMALLER_THAN_INT() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00111 inline static bool _USING_ALL_BITS() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00112 inline static value_type _ONE() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00113 inline static value_type _F_MASK() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00114 inline static float _EPSILON() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00115
00116 class raw { };
00117 public:
00118 fixed_base()ETL_ATTRIB_INLINE;
00119 fixed_base(const float &f)ETL_ATTRIB_INLINE;
00120 fixed_base(const double &f)ETL_ATTRIB_INLINE;
00121 fixed_base(const long double &f)ETL_ATTRIB_INLINE;
00122 fixed_base(const int &i)ETL_ATTRIB_INLINE;
00123 fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE;
00124 fixed_base(const _fixed &x)ETL_ATTRIB_INLINE;
00125 fixed_base(value_type x,raw)ETL_ATTRIB_INLINE;
00126
00127 T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
00128 const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
00129
00130 const _fixed& operator+=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00131 const _fixed& operator-=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00132 template<typename U> const _fixed& operator*=(const U &rhs) ETL_ATTRIB_INLINE;
00133 template<typename U> const _fixed& operator/=(const U &rhs) ETL_ATTRIB_INLINE;
00134 const _fixed& operator*=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00135 const _fixed& operator/=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00136 const _fixed& operator*=(const int &rhs) ETL_ATTRIB_INLINE;
00137 const _fixed& operator/=(const int &rhs) ETL_ATTRIB_INLINE;
00138
00139
00140 template<typename U> _fixed operator+(const U &rhs)const ETL_ATTRIB_INLINE;
00141 template<typename U> _fixed operator-(const U &rhs)const ETL_ATTRIB_INLINE;
00142 template<typename U> _fixed operator*(const U &rhs)const ETL_ATTRIB_INLINE;
00143 template<typename U> _fixed operator/(const U &rhs)const ETL_ATTRIB_INLINE;
00144 _fixed operator+(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00145 _fixed operator-(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00146 _fixed operator*(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00147 _fixed operator/(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00148 _fixed operator*(const int &rhs)const ETL_ATTRIB_INLINE;
00149 _fixed operator/(const int &rhs)const ETL_ATTRIB_INLINE;
00150 _fixed operator*(const float &rhs)const ETL_ATTRIB_INLINE;
00151 _fixed operator*(const double &rhs)const ETL_ATTRIB_INLINE;
00152
00153
00154 _fixed operator-()const ETL_ATTRIB_INLINE;
00155
00156
00157 inline operator float()const ETL_ATTRIB_INLINE;
00158 inline operator double()const ETL_ATTRIB_INLINE;
00159 inline operator long double()const ETL_ATTRIB_INLINE;
00160 inline operator int()const ETL_ATTRIB_INLINE;
00161 inline operator bool()const ETL_ATTRIB_INLINE;
00162
00163 _fixed floor()const;
00164 _fixed ceil()const;
00165 _fixed round()const;
00166
00167 bool operator==(const _fixed &rhs)const { return data()==rhs.data(); }
00168 bool operator!=(const _fixed &rhs)const { return data()!=rhs.data(); }
00169 bool operator<(const _fixed &rhs)const { return data()<rhs.data(); }
00170 bool operator>(const _fixed &rhs)const { return data()>rhs.data(); }
00171 bool operator<=(const _fixed &rhs)const { return data()<=rhs.data(); }
00172 bool operator>=(const _fixed &rhs)const { return data()>=rhs.data(); }
00173 };
00174
00175
00176 template <class T,unsigned int FIXED_BITS>
00177 fixed_base<T,FIXED_BITS>::fixed_base()
00178 {}
00179
00180 template <class T,unsigned int FIXED_BITS>
00181 fixed_base<T,FIXED_BITS>::fixed_base(const _fixed &x):_data(x._data)
00182 {}
00183
00184 template <class T,unsigned int FIXED_BITS>
00185 fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()
00186 #ifdef ROUND_TO_NEAREST_INTEGER
00187 +0.5f
00188 #endif
00189 )) {}
00190
00191 template <class T,unsigned int FIXED_BITS>
00192 fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()
00193 #ifdef ROUND_TO_NEAREST_INTEGER
00194 +0.5
00195 #endif
00196 )) {}
00197
00198 template <class T,unsigned int FIXED_BITS>
00199 fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()
00200 #ifdef ROUND_TO_NEAREST_INTEGER
00201 +0.5
00202 #endif
00203 )) {}
00204
00205 template <class T,unsigned int FIXED_BITS>
00206 fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
00207 {}
00208
00209 template <class T,unsigned int FIXED_BITS>
00210 fixed_base<T,FIXED_BITS>::fixed_base(value_type x,raw):_data(x) { }
00211
00212 template <class T,unsigned int FIXED_BITS>
00213 fixed_base<T,FIXED_BITS>::fixed_base(const int &n,const int &d):_data((n<<FIXED_BITS)/d) { }
00214
00215
00216
00217 template <class T,unsigned int FIXED_BITS> inline bool
00218 fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT()
00219 {
00220 return sizeof(T)<sizeof(int);
00221 }
00222
00223 template <class T,unsigned int FIXED_BITS> inline bool
00224 fixed_base<T,FIXED_BITS>::_USING_ALL_BITS()
00225 {
00226 return sizeof(T)*8==FIXED_BITS;
00227 }
00228
00229 template <class T,unsigned int FIXED_BITS> inline T
00230 fixed_base<T,FIXED_BITS>::_ONE()
00231 {
00232 return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
00233 }
00234
00235 template <class T,unsigned int FIXED_BITS> inline T
00236 fixed_base<T,FIXED_BITS>::_F_MASK()
00237 {
00238 return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
00239 }
00240
00241 template <class T,unsigned int FIXED_BITS> inline float
00242 fixed_base<T,FIXED_BITS>::_EPSILON()
00243 {
00244 return 1.0f/((float)_ONE()*2);
00245 }
00246
00247
00248 template <class T,unsigned int FIXED_BITS>T &
00249 fixed_base<T,FIXED_BITS>::data()
00250 {
00251 return _data;
00252 }
00253
00254 template <class T,unsigned int FIXED_BITS>const T &
00255 fixed_base<T,FIXED_BITS>::data()const
00256 {
00257 return _data;
00258 }
00259
00261 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00262 fixed_base<T,FIXED_BITS>::operator+=(const _fixed &rhs)
00263 {
00264 _data+=rhs._data;
00265 return *this;
00266 }
00267
00269 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00270 fixed_base<T,FIXED_BITS>::operator-=(const _fixed &rhs)
00271 {
00272 _data-=rhs._data;
00273 return *this;
00274 }
00275
00277 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00278 fixed_base<T,FIXED_BITS>::operator*=(const _fixed &rhs)
00279 {
00280 if(_TYPE_SMALLER_THAN_INT())
00281 _data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
00282 else
00283 {
00284 _data*=rhs._data;
00285 _data>>=FIXED_BITS;
00286 }
00287
00288 return *this;
00289 }
00290
00292 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00293 fixed_base<T,FIXED_BITS>::operator/=(const _fixed &rhs)
00294 {
00295 if(_TYPE_SMALLER_THAN_INT())
00296 _data=static_cast<T>((int)_data/(int)rhs._data<<FIXED_BITS);
00297 else
00298 {
00299 _data/=rhs._data;
00300 _data<<=FIXED_BITS;
00301 }
00302 return *this;
00303 }
00304
00305 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
00306 fixed_base<T,FIXED_BITS>::operator*=(const U &rhs)
00307 {
00308 return operator*=(fixed_base<T,FIXED_BITS>(rhs));
00309 }
00310
00311 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
00312 fixed_base<T,FIXED_BITS>::operator/=(const U &rhs)
00313 {
00314 return operator/=(fixed_base<T,FIXED_BITS>(rhs));
00315 }
00316
00318 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00319 fixed_base<T,FIXED_BITS>::operator*=(const int &rhs)
00320 {
00321 _data*=rhs; return *this;
00322 }
00323
00325 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00326 fixed_base<T,FIXED_BITS>::operator/=(const int &rhs)
00327 {
00328 _data/=rhs; return *this;
00329 }
00330
00331
00332
00333
00334
00335
00336
00338 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00339 fixed_base<T,FIXED_BITS>::operator+(const _fixed &rhs)const
00340 {
00341 _fixed ret;
00342 ret._data=_data+rhs._data;
00343 return ret;
00344 }
00345
00347 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00348 fixed_base<T,FIXED_BITS>::operator-(const _fixed &rhs)const
00349 {
00350 _fixed ret;
00351 ret._data=_data-rhs._data;
00352 return ret;
00353 }
00354
00356 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00357 fixed_base<T,FIXED_BITS>::operator*(const _fixed &rhs)const
00358 {
00359 _fixed ret;
00360 ret._data=((_data*rhs._data)>>FIXED_BITS);
00361 return ret;
00362
00363 }
00364
00366 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00367 fixed_base<T,FIXED_BITS>::operator/(const _fixed &rhs)const
00368 {
00369 _fixed ret;
00370 ret._data=((_data/rhs._data)<<FIXED_BITS);
00371 return ret;
00372
00373 }
00374
00376 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00377 fixed_base<T,FIXED_BITS>::operator+(const U &rhs) const
00378 {
00379 return operator+(fixed_base<T,FIXED_BITS>(rhs));
00380 }
00381
00383 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00384 fixed_base<T,FIXED_BITS>::operator-(const U &rhs) const
00385 {
00386 return operator-(fixed_base<T,FIXED_BITS>(rhs));
00387 }
00388
00390 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00391 fixed_base<T,FIXED_BITS>::operator*(const U &rhs) const
00392 {
00393 return operator*(fixed_base<T,FIXED_BITS>(rhs));
00394 }
00395
00397 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00398 fixed_base<T,FIXED_BITS>::operator/(const U &rhs) const
00399 {
00400 return operator/(fixed_base<T,FIXED_BITS>(rhs));
00401 }
00402
00404 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00405 fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const
00406 {
00407 _fixed ret;
00408 ret._data=_data*rhs;
00409 return ret;
00410
00411 }
00412
00414 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00415 fixed_base<T,FIXED_BITS>::operator*(const float &rhs)const
00416 {
00417 return (*this)*_fixed(rhs);
00418 }
00419
00421 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00422 fixed_base<T,FIXED_BITS>::operator*(const double &rhs)const
00423 {
00424 return (*this)*_fixed(rhs);
00425 }
00426
00427
00429 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00430 fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const
00431 {
00432 _fixed ret;
00433 ret._data=_data/rhs;
00434 return ret;
00435
00436 }
00437
00439 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00440 operator*(const float& lhs, const fixed_base<T,FIXED_BITS> &rhs)
00441 {
00442 return rhs*lhs;
00443 }
00444
00446 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00447 operator*(const double& lhs, const fixed_base<T,FIXED_BITS> &rhs)
00448 {
00449 return rhs*lhs;
00450 }
00451
00452
00453
00454
00455
00456
00457
00458 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00459 fixed_base<T,FIXED_BITS>::operator-()const
00460 {
00461 _fixed ret; ret._data=-_data; return ret;
00462 }
00463
00464
00465 template <class T,unsigned int FIXED_BITS>
00466 fixed_base<T,FIXED_BITS>::operator float()const
00467 {
00468 return static_cast<float>(_data)/static_cast<float>(_ONE());
00469 }
00470
00471 template <class T,unsigned int FIXED_BITS>
00472 fixed_base<T,FIXED_BITS>::operator double()const
00473 {
00474 return static_cast<double>(_data)/static_cast<double>(_ONE());
00475 }
00476
00477 template <class T,unsigned int FIXED_BITS>
00478 fixed_base<T,FIXED_BITS>::operator long double()const
00479 {
00480 return static_cast<long double>(_data)/static_cast<long double>(_ONE());
00481 }
00482
00483 template <class T,unsigned int FIXED_BITS>
00484 fixed_base<T,FIXED_BITS>::operator int()const
00485 {
00486 return static_cast<int>(_data>>FIXED_BITS);
00487 }
00488
00489 template <class T,unsigned int FIXED_BITS>
00490 fixed_base<T,FIXED_BITS>::operator bool()const
00491 {
00492 return static_cast<bool>(_data);
00493 }
00494
00495
00496 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
00497 fixed_base<T,FIXED_BITS>::floor()const
00498 {
00499 _fixed ret(*this);
00500 ret._data&=~_F_MASK();
00501 return ret;
00502 }
00503
00504 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
00505 fixed_base<T,FIXED_BITS>::ceil()const
00506 {
00507 _fixed ret(*this);
00508 if(ret._data&_F_MASK())
00509 ret._data=(ret._data&~_F_MASK()) + _ONE();
00510 else
00511 ret._data&=~_F_MASK();
00512 return ret;
00513 }
00514
00515 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
00516 fixed_base<T,FIXED_BITS>::round()const
00517 {
00518 _fixed ret(*this);
00519 ret._data+=_ONE()>>1;
00520 ret._data&=~_F_MASK();
00521 return ret;
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 typedef fixed_base<ETL_FIXED_TYPE,ETL_FIXED_BITS> fixed;
00550
00551 _ETL_END_NAMESPACE
00552
00553 _STD_BEGIN_NAMESPACE
00554
00555 template <class T,unsigned int FIXED_BITS>
00556 inline _ETL::fixed_base<T,FIXED_BITS>
00557 ceil(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00558 { return rhs.ceil(); }
00559
00560 template <class T,unsigned int FIXED_BITS>
00561 _ETL::fixed_base<T,FIXED_BITS>
00562 floor(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00563 { return rhs.floor(); }
00564
00565 template <class T,unsigned int FIXED_BITS>
00566 _ETL::fixed_base<T,FIXED_BITS>
00567 round(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00568 { return rhs.round(); }
00569
00570 template <class T,unsigned int FIXED_BITS>
00571 _ETL::fixed_base<T,FIXED_BITS>
00572 abs(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00573 { return rhs<_ETL::fixed_base<T,FIXED_BITS>(0)?-rhs:rhs; }
00574
00575 _STD_END_NAMESPACE
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 #if defined(__GNUC__) && __GNUC__ == 3
00605 template <class T,unsigned int FIXED_BITS, typename U> U
00606 operator*(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00607 { return a*static_cast<double>(b); }
00608
00609 template <class T,unsigned int FIXED_BITS, typename U> U
00610 operator/(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00611 { return a/static_cast<double>(b); }
00612
00613 template <class T,unsigned int FIXED_BITS, typename U> U
00614 operator+(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00615 { return a+static_cast<double>(b); }
00616
00617 template <class T,unsigned int FIXED_BITS, typename U> U
00618 operator-(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00619 { return a-static_cast<double>(b); }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 #endif
00640
00641
00642
00643 #endif