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