ETL  0.04.19
_fixed.h
Go to the documentation of this file.
1 
26 /* === S T A R T =========================================================== */
27 
28 #ifndef __ETL__FIXED_H
29 #define __ETL__FIXED_H
30 
31 /* === H E A D E R S ======================================================= */
32 
33 #include <cmath>
34 
35 /* === M A C R O S ========================================================= */
36 
37 // the "+0.5" code was commented out - maybe to make thing run faster?
38 // it can be re-enabled by uncommenting this next line:
39 // #define ROUND_TO_NEAREST_INTEGER
40 
41 #ifndef ETL_FIXED_TYPE
42 # define ETL_FIXED_TYPE int
43 #endif
44 
45 #ifndef ETL_FIXED_BITS
46 #define ETL_FIXED_BITS 12
47 #endif
48 
49 #ifndef ETL_FIXED_EPSILON
50 #define ETL_FIXED_EPSILON _EPSILON()
51 #endif
52 
53 #ifdef __GNUC___
54 #define ETL_ATTRIB_CONST __attribute__ ((const))
55 #define ETL_ATTRIB_PURE __attribute__ ((pure))
56 #define ETL_ATTRIB_INLINE __attribute__ ((always_inline))
57 #else
58 #define ETL_ATTRIB_CONST
59 #define ETL_ATTRIB_PURE
60 #define ETL_ATTRIB_INLINE
61 #endif
62 
63 /* === C L A S S E S & S T R U C T S ======================================= */
64 
66 
67 // Forward declarations
68 template<typename T, unsigned int FIXED_BITS> class fixed_base;
69 //template<> class fixed_base<char>;
70 
72 
74 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> abs(const _ETL::fixed_base<T,FIXED_BITS>&);
75 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cos(const _ETL::fixed_base<T,FIXED_BITS>&);
76 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cosh(const _ETL::fixed_base<T,FIXED_BITS>&);
77 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> exp(const _ETL::fixed_base<T,FIXED_BITS>&);
78 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log(const _ETL::fixed_base<T,FIXED_BITS>&);
79 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log10(const _ETL::fixed_base<T,FIXED_BITS>&);
80 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, int);
81 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const T&);
82 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&,
83  const _ETL::fixed_base<T,FIXED_BITS>&);
84 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>&);
85 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sin(const _ETL::fixed_base<T,FIXED_BITS>&);
86 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sinh(const _ETL::fixed_base<T,FIXED_BITS>&);
87 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sqrt(const _ETL::fixed_base<T,FIXED_BITS>&);
88 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tan(const _ETL::fixed_base<T,FIXED_BITS>&);
89 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tanh(const _ETL::fixed_base<T,FIXED_BITS>&);
92 
99 template <class T,unsigned int FIXED_BITS>
101 {
102 public:
103  typedef T value_type;
104 private:
105  T _data;
106 
109 
111  inline static bool _USING_ALL_BITS() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
112  inline static value_type _ONE() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
113  inline static value_type _F_MASK() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
114  inline static float _EPSILON() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
115 
116  class raw { };
117 public:
119  fixed_base(const float &f)ETL_ATTRIB_INLINE;
120  fixed_base(const double &f)ETL_ATTRIB_INLINE;
121  fixed_base(const long double &f)ETL_ATTRIB_INLINE;
122  fixed_base(const int &i)ETL_ATTRIB_INLINE;
123  fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE;
124  fixed_base(const _fixed &x)ETL_ATTRIB_INLINE;
125  fixed_base(value_type x,raw)ETL_ATTRIB_INLINE;
126 
127  T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
128  const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
129 
130  const _fixed& operator+=(const _fixed &rhs) ETL_ATTRIB_INLINE;
131  const _fixed& operator-=(const _fixed &rhs) ETL_ATTRIB_INLINE;
132  template<typename U> const _fixed& operator*=(const U &rhs) ETL_ATTRIB_INLINE;
133  template<typename U> const _fixed& operator/=(const U &rhs) ETL_ATTRIB_INLINE;
134  const _fixed& operator*=(const _fixed &rhs) ETL_ATTRIB_INLINE;
135  const _fixed& operator/=(const _fixed &rhs) ETL_ATTRIB_INLINE;
136  const _fixed& operator*=(const int &rhs) ETL_ATTRIB_INLINE;
137  const _fixed& operator/=(const int &rhs) ETL_ATTRIB_INLINE;
138 
139 
140  template<typename U> _fixed operator+(const U &rhs)const ETL_ATTRIB_INLINE;
141  template<typename U> _fixed operator-(const U &rhs)const ETL_ATTRIB_INLINE;
142  template<typename U> _fixed operator*(const U &rhs)const ETL_ATTRIB_INLINE;
143  template<typename U> _fixed operator/(const U &rhs)const ETL_ATTRIB_INLINE;
144  _fixed operator+(const _fixed &rhs)const ETL_ATTRIB_INLINE;
145  _fixed operator-(const _fixed &rhs)const ETL_ATTRIB_INLINE;
146  _fixed operator*(const _fixed &rhs)const ETL_ATTRIB_INLINE;
147  _fixed operator/(const _fixed &rhs)const ETL_ATTRIB_INLINE;
148  _fixed operator*(const int &rhs)const ETL_ATTRIB_INLINE;
149  _fixed operator/(const int &rhs)const ETL_ATTRIB_INLINE;
150  _fixed operator*(const float &rhs)const ETL_ATTRIB_INLINE;
151  _fixed operator*(const double &rhs)const ETL_ATTRIB_INLINE;
152 
153  // Negation Operator
154  _fixed operator-()const ETL_ATTRIB_INLINE;
155 
156  // Casting Operators
157  inline operator float()const ETL_ATTRIB_INLINE;
158  inline operator double()const ETL_ATTRIB_INLINE;
159  inline operator long double()const ETL_ATTRIB_INLINE;
160  inline operator int()const ETL_ATTRIB_INLINE;
161  inline operator bool()const ETL_ATTRIB_INLINE;
162 
163  _fixed floor()const;
164  _fixed ceil()const;
165  _fixed round()const;
166 
167  bool operator==(const _fixed &rhs)const { return data()==rhs.data(); }
168  bool operator!=(const _fixed &rhs)const { return data()!=rhs.data(); }
169  bool operator<(const _fixed &rhs)const { return data()<rhs.data(); }
170  bool operator>(const _fixed &rhs)const { return data()>rhs.data(); }
171  bool operator<=(const _fixed &rhs)const { return data()<=rhs.data(); }
172  bool operator>=(const _fixed &rhs)const { return data()>=rhs.data(); }
173 };
174 
175 
176 template <class T,unsigned int FIXED_BITS>
178 {}
179 
180 template <class T,unsigned int FIXED_BITS>
182 {}
183 
184 template <class T,unsigned int FIXED_BITS>
185 fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()
186 #ifdef ROUND_TO_NEAREST_INTEGER
187  +0.5f
188 #endif
189  )) {}
190 
191 template <class T,unsigned int FIXED_BITS>
192 fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()
193 #ifdef ROUND_TO_NEAREST_INTEGER
194  +0.5
195 #endif
196  )) {}
197 
198 template <class T,unsigned int FIXED_BITS>
199 fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()
200 #ifdef ROUND_TO_NEAREST_INTEGER
201  +0.5
202 #endif
203  )) {}
204 
205 template <class T,unsigned int FIXED_BITS>
206 fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
207 {}
208 
209 template <class T,unsigned int FIXED_BITS>
211 
212 template <class T,unsigned int FIXED_BITS>
213 fixed_base<T,FIXED_BITS>::fixed_base(const int &n,const int &d):_data((n<<FIXED_BITS)/d) { }
214 
215 
216 
217 template <class T,unsigned int FIXED_BITS> inline bool
219 {
220  return sizeof(T)<sizeof(int);
221 }
222 
223 template <class T,unsigned int FIXED_BITS> inline bool
225 {
226  return sizeof(T)*8==FIXED_BITS;
227 }
228 
229 template <class T,unsigned int FIXED_BITS> inline T
231 {
232  return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
233 }
234 
235 template <class T,unsigned int FIXED_BITS> inline T
237 {
238  return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
239 }
240 
241 template <class T,unsigned int FIXED_BITS> inline float
243 {
244  return 1.0f/((float)_ONE()*2);
245 }
246 
247 
248 template <class T,unsigned int FIXED_BITS>T &
250 {
251  return _data;
252 }
253 
254 template <class T,unsigned int FIXED_BITS>const T &
256 {
257  return _data;
258 }
259 
261 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
263 {
264  _data+=rhs._data;
265  return *this;
266 }
267 
269 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
271 {
272  _data-=rhs._data;
273  return *this;
274 }
275 
277 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
279 {
280  if(_TYPE_SMALLER_THAN_INT())
281  _data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
282  else
283  {
284  _data*=rhs._data;
285  _data>>=FIXED_BITS;
286  }
287 
288  return *this;
289 }
290 
292 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
294 {
295  if(_TYPE_SMALLER_THAN_INT())
296  _data=static_cast<T>((int)_data/(int)rhs._data<<FIXED_BITS);
297  else
298  {
299  _data/=rhs._data;
300  _data<<=FIXED_BITS;
301  }
302  return *this;
303 }
304 
305 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
307 {
308  return operator*=(fixed_base<T,FIXED_BITS>(rhs));
309 }
310 
311 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
313 {
314  return operator/=(fixed_base<T,FIXED_BITS>(rhs));
315 }
316 
318 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
320 {
321  _data*=rhs; return *this;
322 }
323 
325 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
327 {
328  _data/=rhs; return *this;
329 }
330 
331 
332 
333 
334 
335 
336 
338 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
340 {
341  _fixed ret;
342  ret._data=_data+rhs._data;
343  return ret;
344 }
345 
347 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
349 {
350  _fixed ret;
351  ret._data=_data-rhs._data;
352  return ret;
353 }
354 
356 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
358 {
359  _fixed ret;
360  ret._data=((_data*rhs._data)>>FIXED_BITS);
361  return ret;
362  //return reinterpret_cast<_fixed>((_data*rhs._data)>>FIXED_BITS);
363 }
364 
366 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
368 {
369  _fixed ret;
370  ret._data=((_data/rhs._data)<<FIXED_BITS);
371  return ret;
372  //return reinterpret_cast<_fixed>((_data/rhs._data)<<FIXED_BITS);
373 }
374 
376 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
378 {
379  return operator+(fixed_base<T,FIXED_BITS>(rhs));
380 }
381 
383 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
385 {
386  return operator-(fixed_base<T,FIXED_BITS>(rhs));
387 }
388 
390 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
392 {
393  return operator*(fixed_base<T,FIXED_BITS>(rhs));
394 }
395 
397 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
399 {
400  return operator/(fixed_base<T,FIXED_BITS>(rhs));
401 }
402 
404 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
406 {
407  _fixed ret;
408  ret._data=_data*rhs;
409  return ret;
410  //return reinterpret_cast<_fixed>(_data*rhs);
411 }
412 
414 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
416 {
417  return (*this)*_fixed(rhs);
418 }
419 
421 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
422 fixed_base<T,FIXED_BITS>::operator*(const double &rhs)const
423 {
424  return (*this)*_fixed(rhs);
425 }
426 
427 
429 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
431 {
432  _fixed ret;
433  ret._data=_data/rhs;
434  return ret;
435  //return reinterpret_cast<_fixed>(_data/rhs);
436 }
437 
439 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
440 operator*(const float& lhs, const fixed_base<T,FIXED_BITS> &rhs)
441 {
442  return rhs*lhs;
443 }
444 
446 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
447 operator*(const double& lhs, const fixed_base<T,FIXED_BITS> &rhs)
448 {
449  return rhs*lhs;
450 }
451 
452 
453 
454 
455 
456 
457 // Negation Operator
458 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
460 {
461  _fixed ret; ret._data=-_data; return ret;
462 }
463 
464 // Casting Operators
465 template <class T,unsigned int FIXED_BITS>
467 {
468  return static_cast<float>(_data)/static_cast<float>(_ONE());
469 }
470 
471 template <class T,unsigned int FIXED_BITS>
473 {
474  return static_cast<double>(_data)/static_cast<double>(_ONE());
475 }
476 
477 template <class T,unsigned int FIXED_BITS>
479 {
480  return static_cast<long double>(_data)/static_cast<long double>(_ONE());
481 }
482 
483 template <class T,unsigned int FIXED_BITS>
485 {
486  return static_cast<int>(_data>>FIXED_BITS);
487 }
488 
489 template <class T,unsigned int FIXED_BITS>
491 {
492  return static_cast<bool>(_data);
493 }
494 
495 
496 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
498 {
499  _fixed ret(*this);
500  ret._data&=~_F_MASK();
501  return ret;
502 }
503 
504 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
506 {
507  _fixed ret(*this);
508  if(ret._data&_F_MASK())
509  ret._data=(ret._data&~_F_MASK()) + _ONE();
510  else
511  ret._data&=~_F_MASK();
512  return ret;
513 }
514 
515 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
517 {
518  _fixed ret(*this);
519  ret._data+=_ONE()>>1;
520  ret._data&=~_F_MASK();
521  return ret;
522 }
523 
524 
525 
526 
527 
528 
529 
530 
531 
532 
533 
534 
535 
536 
537 
538 
539 
540 
541 
542 
543 
544 
545 
546 
547 
548 
550 
552 
554 
555 template <class T,unsigned int FIXED_BITS>
556 inline _ETL::fixed_base<T,FIXED_BITS>
557 ceil(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
558 { return rhs.ceil(); }
559 
560 template <class T,unsigned int FIXED_BITS>
561 _ETL::fixed_base<T,FIXED_BITS>
562 floor(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
563 { return rhs.floor(); }
564 
565 template <class T,unsigned int FIXED_BITS>
566 _ETL::fixed_base<T,FIXED_BITS>
567 round(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
568 { return rhs.round(); }
569 
570 template <class T,unsigned int FIXED_BITS>
571 _ETL::fixed_base<T,FIXED_BITS>
572 abs(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
573 { return rhs<_ETL::fixed_base<T,FIXED_BITS>(0)?-rhs:rhs; }
574 
576 
577 /*
578 template <class T,unsigned int FIXED_BITS, typename U> bool
579 operator==(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
580 { return lhs.data()==rhs.data(); }
581 
582 template <class T,unsigned int FIXED_BITS, typename U> bool
583 operator!=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
584 { return lhs.data()!=rhs.data(); }
585 
586 template <class T,unsigned int FIXED_BITS, typename U> bool
587 operator>(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
588 { return lhs.data()>rhs.data(); }
589 
590 template <class T,unsigned int FIXED_BITS, typename U> bool
591 operator<(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
592 { return lhs.data()<rhs.data(); }
593 
594 template <class T,unsigned int FIXED_BITS, typename U> bool
595 operator>=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
596 { return lhs.data()>=rhs.data(); }
597 
598 template <class T,unsigned int FIXED_BITS, typename U> bool
599 operator<=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
600 { return lhs.data()<=rhs.data(); }
601 */
602 
603 
604 #if defined(__GNUC__) && __GNUC__ == 3
605 template <class T,unsigned int FIXED_BITS, typename U> U
606 operator*(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
607  { return a*static_cast<double>(b); }
608 
609 template <class T,unsigned int FIXED_BITS, typename U> U
610 operator/(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
611  { return a/static_cast<double>(b); }
612 
613 template <class T,unsigned int FIXED_BITS, typename U> U
614 operator+(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
615  { return a+static_cast<double>(b); }
616 
617 template <class T,unsigned int FIXED_BITS, typename U> U
618 operator-(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
619  { return a-static_cast<double>(b); }
620 
621 
622 /*
623 inline const float &
624 operator*=(float &a,const _ETL::fixed &b)
625  { a*=(float)b; return a; }
626 
627 inline const float &
628 operator/=(float &a,const _ETL::fixed &b)
629  { a/=(float)b; return a; }
630 
631 inline const float &
632 operator-=(float &a,const _ETL::fixed &b)
633  { a-=(float)b; return a; }
634 
635 inline const float &
636 operator+=(float &a,const _ETL::fixed &b)
637  { a+=(float)b; return a; }
638 */
639 #endif
640 
641 /* === E N D =============================================================== */
642 
643 #endif