Initial import of ETL
[synfig.git] / ETL / trunk / ETL / _fixed.h
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 $
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 #ifndef ETL_FIXED_TYPE
37 # define ETL_FIXED_TYPE int
38 #endif
39
40 #ifndef ETL_FIXED_BITS
41 #define ETL_FIXED_BITS  12
42 #endif
43
44 #ifndef ETL_FIXED_EPSILON
45 #define ETL_FIXED_EPSILON               _EPSILON()
46 #endif
47
48 #ifdef __GNUC___
49 #define ETL_ATTRIB_CONST        __attribute__ ((const))
50 #define ETL_ATTRIB_PURE         __attribute__ ((pure))
51 #define ETL_ATTRIB_INLINE       __attribute__ ((always_inline))
52 #else
53 #define ETL_ATTRIB_CONST
54 #define ETL_ATTRIB_PURE
55 #define ETL_ATTRIB_INLINE
56 #endif
57
58 /* === C L A S S E S & S T R U C T S ======================================= */
59
60 _ETL_BEGIN_NAMESPACE
61
62 // Forward declarations
63 template<typename T, unsigned int FIXED_BITS> class fixed_base;
64 //template<> class fixed_base<char>;
65
66 _ETL_END_NAMESPACE
67
68 _STD_BEGIN_NAMESPACE
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>&);
85 _STD_END_NAMESPACE
86 _ETL_BEGIN_NAMESPACE
87
88 /*! ========================================================================
89 ** \class       fixed_base
90 ** \brief       Fixed-point template base class
91 **
92 ** A more detailed description needs to be written.
93 */
94 template <class T,unsigned int FIXED_BITS>
95 class fixed_base
96 {
97 public:
98         typedef T value_type;
99 private:
100         T _data;
101         
102         typedef fixed_base<T,FIXED_BITS> _fixed;
103         typedef fixed_base<T,FIXED_BITS> self_type;
104
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;
110
111         class raw { };
112 public:
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;
121
122         T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;    
123         const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
124
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;
133
134
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;
145         
146         // Negation Operator
147         _fixed operator-()const ETL_ATTRIB_INLINE;
148
149         // Casting Operators
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;
155
156         _fixed floor()const;
157         _fixed ceil()const;
158         _fixed round()const;
159         
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(); }
166 };
167
168
169 template <class T,unsigned int FIXED_BITS>
170 fixed_base<T,FIXED_BITS>::fixed_base()
171 {}      
172
173 template <class T,unsigned int FIXED_BITS>
174 fixed_base<T,FIXED_BITS>::fixed_base(const _fixed &x):_data(x._data)
175 {}
176
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))
179 {}
180
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))
183 {}
184
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))
187 {}
188
189 template <class T,unsigned int FIXED_BITS>
190 fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
191 {}
192
193 template <class T,unsigned int FIXED_BITS>
194 fixed_base<T,FIXED_BITS>::fixed_base(value_type x,raw):_data(x) { }
195
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) { }
198         
199         
200
201 template <class T,unsigned int FIXED_BITS> inline bool
202 fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT() 
203 {
204         return sizeof(T)<sizeof(int);
205 }       
206
207 template <class T,unsigned int FIXED_BITS> inline bool
208 fixed_base<T,FIXED_BITS>::_USING_ALL_BITS() 
209 {
210         return sizeof(T)*8==FIXED_BITS;
211 }
212
213 template <class T,unsigned int FIXED_BITS> inline T
214 fixed_base<T,FIXED_BITS>::_ONE() 
215 {
216         return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
217 }
218
219 template <class T,unsigned int FIXED_BITS> inline T
220 fixed_base<T,FIXED_BITS>::_F_MASK() 
221 {
222         return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
223 }
224
225 template <class T,unsigned int FIXED_BITS> inline float
226 fixed_base<T,FIXED_BITS>::_EPSILON() 
227 {
228         return 1.0f/((float)_ONE()*2);
229 }
230
231
232 template <class T,unsigned int FIXED_BITS>T &
233 fixed_base<T,FIXED_BITS>::data() 
234 {
235         return _data;
236 }
237
238 template <class T,unsigned int FIXED_BITS>const T &
239 fixed_base<T,FIXED_BITS>::data()const 
240 {
241         return _data;
242 }
243
244 //! fixed+=fixed
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) 
247 {
248         _data+=rhs._data;
249         return *this;
250 }
251
252 //! fixed-=fixed
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) 
255 {
256         _data-=rhs._data;
257         return *this;
258 }
259
260 //! fixed*=fixed
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) 
263 {
264         if(_TYPE_SMALLER_THAN_INT())
265                 _data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
266         else
267         {
268                 _data*=rhs._data;
269                 _data>>=FIXED_BITS;
270         }
271                 
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         return *this;
287 }
288
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) 
291 {
292         return operator*=(fixed_base<T,FIXED_BITS>(rhs));
293 }
294
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) 
297 {
298         return operator/=(fixed_base<T,FIXED_BITS>(rhs));
299 }
300
301 //! fixed*=int
302 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
303 fixed_base<T,FIXED_BITS>::operator*=(const int &rhs) 
304 {
305         _data*=rhs; return *this;
306 }
307
308 //! fixed/=int
309 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
310 fixed_base<T,FIXED_BITS>::operator/=(const int &rhs) 
311 {
312         _data/=rhs; return *this;
313 }
314
315
316
317
318
319
320
321 //! fixed + fixed
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 
324 {
325         _fixed ret;
326         ret._data=_data+rhs._data;
327         return ret;
328 }
329
330 //! fixed - fixed
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 
333 {
334         _fixed ret;
335         ret._data=_data-rhs._data;
336         return ret;
337 }
338
339 //! fixed * fixed
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 
342 {
343         _fixed ret;
344         ret._data=((_data*rhs._data)>>FIXED_BITS);
345         return ret;
346         //return reinterpret_cast<_fixed>((_data*rhs._data)>>FIXED_BITS);
347 }
348
349 //! fixed / fixed
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 
352 {
353         _fixed ret;
354         ret._data=((_data/rhs._data)<<FIXED_BITS);
355         return ret;
356         //return reinterpret_cast<_fixed>((_data/rhs._data)<<FIXED_BITS);
357 }
358
359 //! fixed + ...
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
362 {
363         return operator+(fixed_base<T,FIXED_BITS>(rhs));
364 }
365
366 //! fixed - ...
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
369 {
370         return operator-(fixed_base<T,FIXED_BITS>(rhs));
371 }
372
373 //! fixed * ...
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
376 {
377         return operator*(fixed_base<T,FIXED_BITS>(rhs));
378 }
379
380 //! fixed / ...
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
383 {
384         return operator/(fixed_base<T,FIXED_BITS>(rhs));
385 }
386
387 //! fixed * int
388 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
389 fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const 
390 {
391         _fixed ret;
392         ret._data=_data*rhs;
393         return ret;
394         //return reinterpret_cast<_fixed>(_data*rhs);
395 }
396
397 //! fixed / int
398 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
399 fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const 
400 {
401         _fixed ret;
402         ret._data=_data/rhs;
403         return ret;
404         //return reinterpret_cast<_fixed>(_data/rhs);
405 }
406
407
408
409
410
411
412
413
414 // Negation Operator
415 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
416 fixed_base<T,FIXED_BITS>::operator-()const 
417 {
418         _fixed ret; ret._data=-_data; return ret;
419 }
420
421 // Casting Operators
422 template <class T,unsigned int FIXED_BITS>
423 fixed_base<T,FIXED_BITS>::operator float()const 
424 {
425         return static_cast<float>(_data)/static_cast<float>(_ONE());
426 }       
427
428 template <class T,unsigned int FIXED_BITS>
429 fixed_base<T,FIXED_BITS>::operator double()const 
430 {
431         return static_cast<double>(_data)/static_cast<double>(_ONE());
432 }       
433
434 template <class T,unsigned int FIXED_BITS>
435 fixed_base<T,FIXED_BITS>::operator long double()const 
436 {
437         return static_cast<long double>(_data)/static_cast<long double>(_ONE());
438 }       
439
440 template <class T,unsigned int FIXED_BITS>
441 fixed_base<T,FIXED_BITS>::operator int()const 
442 {
443         return static_cast<int>(_data>>FIXED_BITS);
444 }
445
446 template <class T,unsigned int FIXED_BITS>
447 fixed_base<T,FIXED_BITS>::operator bool()const 
448 {
449         return static_cast<bool>(_data);
450 }
451
452
453 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
454 fixed_base<T,FIXED_BITS>::floor()const
455 {
456         _fixed ret(*this);
457         ret._data&=~_F_MASK();
458         return ret;
459 }
460
461 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
462 fixed_base<T,FIXED_BITS>::ceil()const
463 {
464         _fixed ret(*this);
465         if(ret._data&_F_MASK())
466                 ret._data=(ret._data&~_F_MASK()) + _ONE();
467         else
468                 ret._data&=~_F_MASK();
469         return ret;
470 }
471
472 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
473 fixed_base<T,FIXED_BITS>::round()const
474 {
475         _fixed ret(*this);
476         ret._data+=_ONE()>>1;
477         ret._data&=~_F_MASK();
478         return ret;
479 }
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506 typedef fixed_base<ETL_FIXED_TYPE,ETL_FIXED_BITS> fixed;
507
508 _ETL_END_NAMESPACE
509
510 _STD_BEGIN_NAMESPACE
511
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(); }
516
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(); }
521
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(); }
526
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; }
531
532 _STD_END_NAMESPACE
533
534 /*
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(); }
538
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(); }
542
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(); }
546
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(); }
550
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(); }
554
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(); }
558 */
559
560
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); }
565
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); }
569
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); }
573
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); }
577
578
579 /*
580 inline const float &
581 operator*=(float &a,const _ETL::fixed &b)
582         { a*=(float)b; return a; }
583
584 inline const float &
585 operator/=(float &a,const _ETL::fixed &b)
586         { a/=(float)b; return a; }
587
588 inline const float &
589 operator-=(float &a,const _ETL::fixed &b)
590         { a-=(float)b; return a; }
591
592 inline const float &
593 operator+=(float &a,const _ETL::fixed &b)
594         { a+=(float)b; return a; }
595 */
596 #endif
597
598 /* === E N D =============================================================== */
599
600 #endif