Remove the "** FIXME: THIS DOES NOT ACTUALLY WORK YET" lines.
[synfig.git] / ETL / trunk / ETL / _fixed.h
1 /*! ========================================================================
2 ** Extended Template and Library
3 ** Fixed-Point Math Class Implementation
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 **
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.
12 **
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.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** This is an internal header file, included by other ETL headers.
21 ** You should not attempt to use it directly.
22 **
23 ** ========================================================================= */
24
25 /* === S T A R T =========================================================== */
26
27 #ifndef __ETL__FIXED_H
28 #define __ETL__FIXED_H
29
30 /* === H E A D E R S ======================================================= */
31
32 #include <cmath>
33
34 /* === M A C R O S ========================================================= */
35
36 // the "+0.5" code was commented out - maybe to make thing run faster?
37 // it can be re-enabled by uncommenting this next line:
38 // #define ROUND_TO_NEAREST_INTEGER
39
40 #ifndef ETL_FIXED_TYPE
41 # define ETL_FIXED_TYPE int
42 #endif
43
44 #ifndef ETL_FIXED_BITS
45 #define ETL_FIXED_BITS  12
46 #endif
47
48 #ifndef ETL_FIXED_EPSILON
49 #define ETL_FIXED_EPSILON               _EPSILON()
50 #endif
51
52 #ifdef __GNUC___
53 #define ETL_ATTRIB_CONST        __attribute__ ((const))
54 #define ETL_ATTRIB_PURE         __attribute__ ((pure))
55 #define ETL_ATTRIB_INLINE       __attribute__ ((always_inline))
56 #else
57 #define ETL_ATTRIB_CONST
58 #define ETL_ATTRIB_PURE
59 #define ETL_ATTRIB_INLINE
60 #endif
61
62 /* === C L A S S E S & S T R U C T S ======================================= */
63
64 _ETL_BEGIN_NAMESPACE
65
66 // Forward declarations
67 template<typename T, unsigned int FIXED_BITS> class fixed_base;
68 //template<> class fixed_base<char>;
69
70 _ETL_END_NAMESPACE
71
72 _STD_BEGIN_NAMESPACE
73 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> abs(const _ETL::fixed_base<T,FIXED_BITS>&);
74 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cos(const _ETL::fixed_base<T,FIXED_BITS>&);
75 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cosh(const _ETL::fixed_base<T,FIXED_BITS>&);
76 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> exp(const _ETL::fixed_base<T,FIXED_BITS>&);
77 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log(const _ETL::fixed_base<T,FIXED_BITS>&);
78 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log10(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>&, int);
80 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const T&);
81 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&,
82                                         const _ETL::fixed_base<T,FIXED_BITS>&);
83 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>&);
84 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sin(const _ETL::fixed_base<T,FIXED_BITS>&);
85 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sinh(const _ETL::fixed_base<T,FIXED_BITS>&);
86 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sqrt(const _ETL::fixed_base<T,FIXED_BITS>&);
87 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tan(const _ETL::fixed_base<T,FIXED_BITS>&);
88 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tanh(const _ETL::fixed_base<T,FIXED_BITS>&);
89 _STD_END_NAMESPACE
90 _ETL_BEGIN_NAMESPACE
91
92 /*! ========================================================================
93 ** \class       fixed_base
94 ** \brief       Fixed-point template base class
95 **
96 ** A more detailed description needs to be written.
97 */
98 template <class T,unsigned int FIXED_BITS>
99 class fixed_base
100 {
101 public:
102         typedef T value_type;
103 private:
104         T _data;
105
106         typedef fixed_base<T,FIXED_BITS> _fixed;
107         typedef fixed_base<T,FIXED_BITS> self_type;
108
109         inline static bool _TYPE_SMALLER_THAN_INT() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
110         inline static bool _USING_ALL_BITS() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
111         inline static value_type _ONE() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
112         inline static value_type _F_MASK() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
113         inline static float _EPSILON() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
114
115         class raw { };
116 public:
117         fixed_base()ETL_ATTRIB_INLINE;
118         fixed_base(const float &f)ETL_ATTRIB_INLINE;
119         fixed_base(const double &f)ETL_ATTRIB_INLINE;
120         fixed_base(const long double &f)ETL_ATTRIB_INLINE;
121         fixed_base(const int &i)ETL_ATTRIB_INLINE;
122         fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE; //!< Fraction constructor
123         fixed_base(const _fixed &x)ETL_ATTRIB_INLINE;
124         fixed_base(value_type x,raw)ETL_ATTRIB_INLINE;
125
126         T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
127         const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
128
129         const _fixed& operator+=(const _fixed &rhs) ETL_ATTRIB_INLINE;
130         const _fixed& operator-=(const _fixed &rhs) ETL_ATTRIB_INLINE;
131         template<typename U> const _fixed& operator*=(const U &rhs) ETL_ATTRIB_INLINE;
132         template<typename U> const _fixed& operator/=(const U &rhs) ETL_ATTRIB_INLINE;
133         const _fixed& operator*=(const _fixed &rhs) ETL_ATTRIB_INLINE;
134         const _fixed& operator/=(const _fixed &rhs) ETL_ATTRIB_INLINE;
135         const _fixed& operator*=(const int &rhs) ETL_ATTRIB_INLINE;
136         const _fixed& operator/=(const int &rhs) ETL_ATTRIB_INLINE;
137
138
139         template<typename U> _fixed operator+(const U &rhs)const ETL_ATTRIB_INLINE;
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         _fixed operator+(const _fixed &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 int &rhs)const ETL_ATTRIB_INLINE;
148         _fixed operator/(const int &rhs)const ETL_ATTRIB_INLINE;
149         _fixed operator*(const float &rhs)const ETL_ATTRIB_INLINE;
150         _fixed operator*(const double &rhs)const ETL_ATTRIB_INLINE;
151
152         // Negation Operator
153         _fixed operator-()const ETL_ATTRIB_INLINE;
154
155         // Casting Operators
156         inline operator float()const ETL_ATTRIB_INLINE;
157         inline operator double()const ETL_ATTRIB_INLINE;
158         inline operator long double()const ETL_ATTRIB_INLINE;
159         inline operator int()const ETL_ATTRIB_INLINE;
160         inline operator bool()const ETL_ATTRIB_INLINE;
161
162         _fixed floor()const;
163         _fixed ceil()const;
164         _fixed round()const;
165
166         bool operator==(const _fixed &rhs)const { return data()==rhs.data(); }
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 };
173
174
175 template <class T,unsigned int FIXED_BITS>
176 fixed_base<T,FIXED_BITS>::fixed_base()
177 {}
178
179 template <class T,unsigned int FIXED_BITS>
180 fixed_base<T,FIXED_BITS>::fixed_base(const _fixed &x):_data(x._data)
181 {}
182
183 template <class T,unsigned int FIXED_BITS>
184 fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()
185 #ifdef ROUND_TO_NEAREST_INTEGER
186                                                                                                                                                                    +0.5f
187 #endif
188                                                                         )) {}
189
190 template <class T,unsigned int FIXED_BITS>
191 fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()
192 #ifdef ROUND_TO_NEAREST_INTEGER
193                                                                                                                                                                         +0.5
194 #endif
195                                                                         )) {}
196
197 template <class T,unsigned int FIXED_BITS>
198 fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()
199 #ifdef ROUND_TO_NEAREST_INTEGER
200                                                                                                                                                                                  +0.5
201 #endif
202                                                                         )) {}
203
204 template <class T,unsigned int FIXED_BITS>
205 fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
206 {}
207
208 template <class T,unsigned int FIXED_BITS>
209 fixed_base<T,FIXED_BITS>::fixed_base(value_type x,raw):_data(x) { }
210
211 template <class T,unsigned int FIXED_BITS>
212 fixed_base<T,FIXED_BITS>::fixed_base(const int &n,const int &d):_data((n<<FIXED_BITS)/d) { }
213
214
215
216 template <class T,unsigned int FIXED_BITS> inline bool
217 fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT()
218 {
219         return sizeof(T)<sizeof(int);
220 }
221
222 template <class T,unsigned int FIXED_BITS> inline bool
223 fixed_base<T,FIXED_BITS>::_USING_ALL_BITS()
224 {
225         return sizeof(T)*8==FIXED_BITS;
226 }
227
228 template <class T,unsigned int FIXED_BITS> inline T
229 fixed_base<T,FIXED_BITS>::_ONE()
230 {
231         return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
232 }
233
234 template <class T,unsigned int FIXED_BITS> inline T
235 fixed_base<T,FIXED_BITS>::_F_MASK()
236 {
237         return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
238 }
239
240 template <class T,unsigned int FIXED_BITS> inline float
241 fixed_base<T,FIXED_BITS>::_EPSILON()
242 {
243         return 1.0f/((float)_ONE()*2);
244 }
245
246
247 template <class T,unsigned int FIXED_BITS>T &
248 fixed_base<T,FIXED_BITS>::data()
249 {
250         return _data;
251 }
252
253 template <class T,unsigned int FIXED_BITS>const T &
254 fixed_base<T,FIXED_BITS>::data()const
255 {
256         return _data;
257 }
258
259 //! fixed+=fixed
260 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
261 fixed_base<T,FIXED_BITS>::operator+=(const fixed_base<T,FIXED_BITS> &rhs)
262 {
263         _data+=rhs._data;
264         return *this;
265 }
266
267 //! fixed-=fixed
268 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
269 fixed_base<T,FIXED_BITS>::operator-=(const fixed_base<T,FIXED_BITS> &rhs)
270 {
271         _data-=rhs._data;
272         return *this;
273 }
274
275 //! fixed*=fixed
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)
278 {
279         if(_TYPE_SMALLER_THAN_INT())
280                 _data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
281         else
282         {
283                 _data*=rhs._data;
284                 _data>>=FIXED_BITS;
285         }
286
287         return *this;
288 }
289
290 //! fixed/=fixed
291 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
292 fixed_base<T,FIXED_BITS>::operator/=(const fixed_base<T,FIXED_BITS> &rhs)
293 {
294         if(_TYPE_SMALLER_THAN_INT())
295                 _data=static_cast<T>((int)_data/(int)rhs._data<<FIXED_BITS);
296         else
297         {
298                 _data/=rhs._data;
299                 _data<<=FIXED_BITS;
300         }
301         return *this;
302 }
303
304 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
305 fixed_base<T,FIXED_BITS>::operator*=(const U &rhs)
306 {
307         return operator*=(fixed_base<T,FIXED_BITS>(rhs));
308 }
309
310 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
311 fixed_base<T,FIXED_BITS>::operator/=(const U &rhs)
312 {
313         return operator/=(fixed_base<T,FIXED_BITS>(rhs));
314 }
315
316 //! fixed*=int
317 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
318 fixed_base<T,FIXED_BITS>::operator*=(const int &rhs)
319 {
320         _data*=rhs; return *this;
321 }
322
323 //! fixed/=int
324 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
325 fixed_base<T,FIXED_BITS>::operator/=(const int &rhs)
326 {
327         _data/=rhs; return *this;
328 }
329
330
331
332
333
334
335
336 //! fixed + fixed
337 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
338 fixed_base<T,FIXED_BITS>::operator+(const fixed_base<T,FIXED_BITS> &rhs)const
339 {
340         _fixed ret;
341         ret._data=_data+rhs._data;
342         return ret;
343 }
344
345 //! fixed - fixed
346 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
347 fixed_base<T,FIXED_BITS>::operator-(const fixed_base<T,FIXED_BITS> &rhs)const
348 {
349         _fixed ret;
350         ret._data=_data-rhs._data;
351         return ret;
352 }
353
354 //! fixed * fixed
355 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
356 fixed_base<T,FIXED_BITS>::operator*(const fixed_base<T,FIXED_BITS> &rhs)const
357 {
358         _fixed ret;
359         ret._data=((_data*rhs._data)>>FIXED_BITS);
360         return ret;
361         //return reinterpret_cast<_fixed>((_data*rhs._data)>>FIXED_BITS);
362 }
363
364 //! fixed / fixed
365 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
366 fixed_base<T,FIXED_BITS>::operator/(const fixed_base<T,FIXED_BITS> &rhs)const
367 {
368         _fixed ret;
369         ret._data=((_data/rhs._data)<<FIXED_BITS);
370         return ret;
371         //return reinterpret_cast<_fixed>((_data/rhs._data)<<FIXED_BITS);
372 }
373
374 //! fixed + ...
375 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
376 fixed_base<T,FIXED_BITS>::operator+(const U &rhs) const
377 {
378         return operator+(fixed_base<T,FIXED_BITS>(rhs));
379 }
380
381 //! fixed - ...
382 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
383 fixed_base<T,FIXED_BITS>::operator-(const U &rhs) const
384 {
385         return operator-(fixed_base<T,FIXED_BITS>(rhs));
386 }
387
388 //! fixed * ...
389 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
390 fixed_base<T,FIXED_BITS>::operator*(const U &rhs) const
391 {
392         return operator*(fixed_base<T,FIXED_BITS>(rhs));
393 }
394
395 //! fixed / ...
396 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
397 fixed_base<T,FIXED_BITS>::operator/(const U &rhs) const
398 {
399         return operator/(fixed_base<T,FIXED_BITS>(rhs));
400 }
401
402 //! fixed * int
403 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
404 fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const
405 {
406         _fixed ret;
407         ret._data=_data*rhs;
408         return ret;
409         //return reinterpret_cast<_fixed>(_data*rhs);
410 }
411
412 //! fixed * float
413 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
414 fixed_base<T,FIXED_BITS>::operator*(const float &rhs)const
415 {
416     return (*this)*_fixed(rhs);
417 }
418
419 //! fixed * double
420 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
421 fixed_base<T,FIXED_BITS>::operator*(const double &rhs)const
422 {
423     return (*this)*_fixed(rhs);
424 }
425
426
427 //! fixed / int
428 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
429 fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const
430 {
431         _fixed ret;
432         ret._data=_data/rhs;
433         return ret;
434         //return reinterpret_cast<_fixed>(_data/rhs);
435 }
436
437 //! float * fixed
438 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
439 operator*(const float& lhs, const fixed_base<T,FIXED_BITS> &rhs)
440 {
441     return rhs*lhs;
442 }
443
444 //! double * fixed
445 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
446 operator*(const double& lhs, const fixed_base<T,FIXED_BITS> &rhs)
447 {
448     return rhs*lhs;
449 }
450
451
452
453
454
455
456 // Negation Operator
457 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
458 fixed_base<T,FIXED_BITS>::operator-()const
459 {
460         _fixed ret; ret._data=-_data; return ret;
461 }
462
463 // Casting Operators
464 template <class T,unsigned int FIXED_BITS>
465 fixed_base<T,FIXED_BITS>::operator float()const
466 {
467         return static_cast<float>(_data)/static_cast<float>(_ONE());
468 }
469
470 template <class T,unsigned int FIXED_BITS>
471 fixed_base<T,FIXED_BITS>::operator double()const
472 {
473         return static_cast<double>(_data)/static_cast<double>(_ONE());
474 }
475
476 template <class T,unsigned int FIXED_BITS>
477 fixed_base<T,FIXED_BITS>::operator long double()const
478 {
479         return static_cast<long double>(_data)/static_cast<long double>(_ONE());
480 }
481
482 template <class T,unsigned int FIXED_BITS>
483 fixed_base<T,FIXED_BITS>::operator int()const
484 {
485         return static_cast<int>(_data>>FIXED_BITS);
486 }
487
488 template <class T,unsigned int FIXED_BITS>
489 fixed_base<T,FIXED_BITS>::operator bool()const
490 {
491         return static_cast<bool>(_data);
492 }
493
494
495 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
496 fixed_base<T,FIXED_BITS>::floor()const
497 {
498         _fixed ret(*this);
499         ret._data&=~_F_MASK();
500         return ret;
501 }
502
503 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
504 fixed_base<T,FIXED_BITS>::ceil()const
505 {
506         _fixed ret(*this);
507         if(ret._data&_F_MASK())
508                 ret._data=(ret._data&~_F_MASK()) + _ONE();
509         else
510                 ret._data&=~_F_MASK();
511         return ret;
512 }
513
514 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
515 fixed_base<T,FIXED_BITS>::round()const
516 {
517         _fixed ret(*this);
518         ret._data+=_ONE()>>1;
519         ret._data&=~_F_MASK();
520         return ret;
521 }
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 typedef fixed_base<ETL_FIXED_TYPE,ETL_FIXED_BITS> fixed;
549
550 _ETL_END_NAMESPACE
551
552 _STD_BEGIN_NAMESPACE
553
554 template <class T,unsigned int FIXED_BITS>
555 inline _ETL::fixed_base<T,FIXED_BITS>
556 ceil(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
557 { return rhs.ceil(); }
558
559 template <class T,unsigned int FIXED_BITS>
560 _ETL::fixed_base<T,FIXED_BITS>
561 floor(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
562 { return rhs.floor(); }
563
564 template <class T,unsigned int FIXED_BITS>
565 _ETL::fixed_base<T,FIXED_BITS>
566 round(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
567 { return rhs.round(); }
568
569 template <class T,unsigned int FIXED_BITS>
570 _ETL::fixed_base<T,FIXED_BITS>
571 abs(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
572 { return rhs<_ETL::fixed_base<T,FIXED_BITS>(0)?-rhs:rhs; }
573
574 _STD_END_NAMESPACE
575
576 /*
577 template <class T,unsigned int FIXED_BITS, typename U> bool
578 operator==(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
579 { return lhs.data()==rhs.data(); }
580
581 template <class T,unsigned int FIXED_BITS, typename U> bool
582 operator!=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
583 { return lhs.data()!=rhs.data(); }
584
585 template <class T,unsigned int FIXED_BITS, typename U> bool
586 operator>(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
587 { return lhs.data()>rhs.data(); }
588
589 template <class T,unsigned int FIXED_BITS, typename U> bool
590 operator<(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
591 { return lhs.data()<rhs.data(); }
592
593 template <class T,unsigned int FIXED_BITS, typename U> bool
594 operator>=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
595 { return lhs.data()>=rhs.data(); }
596
597 template <class T,unsigned int FIXED_BITS, typename U> bool
598 operator<=(const _ETL::fixed_base<T,FIXED_BITS>& lhs, const _ETL::fixed_base<T,FIXED_BITS>& rhs)
599 { return lhs.data()<=rhs.data(); }
600 */
601
602
603 #if defined(__GNUC__) && __GNUC__ == 3
604 template <class T,unsigned int FIXED_BITS, typename U> U
605 operator*(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
606         { return a*static_cast<double>(b); }
607
608 template <class T,unsigned int FIXED_BITS, typename U> U
609 operator/(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
610         { return a/static_cast<double>(b); }
611
612 template <class T,unsigned int FIXED_BITS, typename U> U
613 operator+(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
614         { return a+static_cast<double>(b); }
615
616 template <class T,unsigned int FIXED_BITS, typename U> U
617 operator-(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
618         { return a-static_cast<double>(b); }
619
620
621 /*
622 inline const float &
623 operator*=(float &a,const _ETL::fixed &b)
624         { a*=(float)b; return a; }
625
626 inline const float &
627 operator/=(float &a,const _ETL::fixed &b)
628         { a/=(float)b; return a; }
629
630 inline const float &
631 operator-=(float &a,const _ETL::fixed &b)
632         { a-=(float)b; return a; }
633
634 inline const float &
635 operator+=(float &a,const _ETL::fixed &b)
636         { a+=(float)b; return a; }
637 */
638 #endif
639
640 /* === E N D =============================================================== */
641
642 #endif