1 // This may look like C code, but it is really -*- C++ -*-
3 Copyright (C) 1988 Free Software Foundation
4 written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
5 adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
7 This file is part of GNU CC.
9 GNU CC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY. No author or distributor
11 accepts responsibility to anyone for the consequences of using it
12 or for whether it serves any particular purpose or works at all,
13 unless he says so in writing. Refer to the GNU CC General Public
14 License for full details.
16 Everyone is granted permission to copy, modify and redistribute
17 GNU CC, but only under the conditions described in the
18 GNU CC General Public License. A copy of this license is
19 supposed to have been given to you along with GNU CC so you
20 can know your rights and responsibilities. It should be in a
21 file named COPYING. Among other things, the copyright notice
22 and this notice must be preserved on all copies.
35 // constant definitions
37 #define Fix16_fs ((double)((unsigned)(1 << 15)))
39 #define Fix16_msb (1 << 15)
40 #define Fix16_m_max ((1 << 15) - 1)
41 #define Fix16_m_min ((short)(1 << 15))
43 #define Fix16_mult Fix16_fs
44 #define Fix16_div (1./Fix16_fs)
45 #define Fix16_max (1. - .5/Fix16_fs)
46 #define Fix16_min (-1.)
49 #define Fix32_fs ((double)((unsigned long)(1 << 31)))
51 #define Fix32_msb ((unsigned long)(1 << 31))
52 #define Fix32_m_max ((1 << 31) - 1)
53 #define Fix32_m_min ((long)(1 << 31))
55 #define Fix32_mult Fix32_fs
56 #define Fix32_div (1./Fix32_fs)
57 #define Fix32_max (1. - .5/Fix32_fs)
58 #define Fix32_min (-1.)
62 // Fix16 class: 16-bit Fixed point data type
64 // consists of a 16-bit mantissa (sign bit & 15 data bits).
73 short round(double d
);
74 short assign(double d
);
89 Fix16
& operator=(Fix16
& f
);
90 Fix16
& operator=(double d
);
91 Fix16
& operator=(Fix32
& f
);
93 friend short& mantissa(Fix16
& f
);
94 friend double value(Fix16
& f
);
99 friend Fix16
operator + (Fix16
& f
, Fix16
& g
);
100 friend Fix16
operator - (Fix16
& f
, Fix16
& g
);
101 friend Fix32
operator * (Fix16
& f
, Fix16
& g
);
102 friend Fix16
operator / (Fix16
& f
, Fix16
& g
);
103 friend Fix16
operator << (Fix16
& f
, int b
);
104 friend Fix16
operator >> (Fix16
& f
, int b
);
106 Fix16
& operator += (Fix16
& f
);
107 Fix16
& operator -= (Fix16
& f
);
108 Fix16
& operator *= (Fix16
& );
109 Fix16
& operator /= (Fix16
& f
);
111 Fix16
& operator <<=(int b
);
112 Fix16
& operator >>=(int b
);
114 friend int operator == (Fix16
& f
, Fix16
& g
);
115 friend int operator != (Fix16
& f
, Fix16
& g
);
116 friend int operator >= (Fix16
& f
, Fix16
& g
);
117 friend int operator <= (Fix16
& f
, Fix16
& g
);
118 friend int operator > (Fix16
& f
, Fix16
& g
);
119 friend int operator < (Fix16
& f
, Fix16
& g
);
121 friend istream
& operator >> (istream
& s
, Fix16
& f
);
122 friend ostream
& operator << (ostream
& s
, Fix16
& f
);
124 void overflow(short&);
125 void range_error(short&);
127 friend Fix16
operator * (Fix16
& f
, int g
);
128 friend Fix16
operator * (int g
, Fix16
& f
);
129 Fix16
& operator *= (int g
);
134 // Fix32 class: 32-bit Fixed point data type
136 // consists of a 32-bit mantissa (sign bit & 31 data bits).
145 long round(double d
);
146 long assign(double d
);
159 Fix32
& operator = (Fix32
& f
);
160 Fix32
& operator = (Fix16
& f
);
161 Fix32
& operator = (double d
);
163 friend long& mantissa(Fix32
& f
);
164 friend double value(Fix32
& f
);
169 friend Fix32
operator + (Fix32
& f
, Fix32
& g
);
170 friend Fix32
operator - (Fix32
& f
, Fix32
& g
);
171 friend Fix32
operator * (Fix32
& f
, Fix32
& g
);
172 friend Fix32
operator / (Fix32
& f
, Fix32
& g
);
173 friend Fix32
operator << (Fix32
& f
, int b
);
174 friend Fix32
operator >> (Fix32
& f
, int b
);
176 friend Fix32
operator * (Fix16
& f
, Fix16
& g
);
178 Fix32
& operator += (Fix32
& f
);
179 Fix32
& operator -= (Fix32
& f
);
180 Fix32
& operator *= (Fix32
& f
);
181 Fix32
& operator /= (Fix32
& f
);
182 Fix32
& operator <<=(int b
);
183 Fix32
& operator >>=(int b
);
185 friend int operator == (Fix32
& f
, Fix32
& g
);
186 friend int operator != (Fix32
& f
, Fix32
& g
);
187 friend int operator >= (Fix32
& f
, Fix32
& g
);
188 friend int operator <= (Fix32
& f
, Fix32
& g
);
189 friend int operator > (Fix32
& f
, Fix32
& g
);
190 friend int operator < (Fix32
& f
, Fix32
& g
);
192 friend istream
& operator >> (istream
& s
, Fix32
& f
);
193 friend ostream
& operator << (ostream
& s
, Fix32
& f
);
195 void overflow(long& i
);
196 void range_error(long& i
);
198 friend Fix32
operator * (Fix32
& f
, int g
);
199 friend Fix32
operator * (int g
, Fix32
& f
);
200 Fix32
& operator *= (int g
);
203 // active error handler declarations
205 typedef void (*Fix16_peh
)(short&);
206 typedef void (*Fix32_peh
)(long&);
208 extern Fix16_peh Fix16_overflow_handler
;
209 extern Fix32_peh Fix32_overflow_handler
;
211 extern Fix16_peh Fix16_range_error_handler
;
212 extern Fix32_peh Fix32_range_error_handler
;
214 #if defined(SHORT_NAMES) || defined(VMS)
215 #define set_overflow_handler sohndl
216 #define set_range_error_handler srnghdl
220 // error handler declarations
222 extern Fix16_peh
set_Fix16_overflow_handler(Fix16_peh
);
223 extern Fix32_peh
set_Fix32_overflow_handler(Fix32_peh
);
224 extern void set_overflow_handler(Fix16_peh
, Fix32_peh
);
226 extern Fix16_peh
set_Fix16_range_error_handler(Fix16_peh
);
227 extern Fix32_peh
set_Fix32_range_error_handler(Fix32_peh
);
228 extern void set_range_error_handler(Fix16_peh
, Fix32_peh
);
231 Fix16_ignore(short&),
232 Fix16_overflow_saturate(short&),
233 Fix16_overflow_warning_saturate(short&),
234 Fix16_warning(short&),
239 Fix32_overflow_saturate(long&),
240 Fix32_overflow_warning_saturate(long&),
241 Fix32_warning(long&),
244 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
246 inline Fix16::~Fix16() {}
248 inline short Fix16::round(double d
)
250 return short( (d
>= 0)? d
+ 0.5 : d
- 0.5);
253 inline Fix16::Fix16(short i
)
258 inline Fix16::Fix16(int i
)
263 inline Fix16::operator double()
265 return Fix16_div
* m
;
268 inline Fix16::Fix16()
273 inline Fix16::Fix16(Fix16
& f
)
278 inline Fix16::Fix16(double d
)
284 inline Fix16
& Fix16::operator=(Fix16
& f
)
290 inline Fix16
& Fix16::operator=(double d
)
297 inline Fix32::Fix32()
302 inline Fix32::Fix32(long i
)
307 inline Fix32:: operator double()
309 return Fix32_div
* m
;
313 inline Fix32::Fix32(Fix32
& f
)
318 inline Fix32::Fix32(Fix16
& f
)
323 inline Fix32::Fix32(double d
)
328 inline Fix16::Fix16(Fix32
& f
)
334 inline Fix16
& Fix16::operator=(Fix32
& f
)
340 inline Fix32
& Fix32::operator=(Fix32
& f
)
346 inline Fix32
& Fix32::operator=(Fix16
& f
)
352 inline Fix32
& Fix32::operator=(double d
)
358 inline short& mantissa(Fix16
& f
)
363 inline double value(Fix16
& f
)
368 inline Fix16
Fix16::operator+()
373 inline Fix16
Fix16::operator-()
378 inline Fix16
operator+(Fix16
& f
, Fix16
& g
)
380 short sum
= f
.m
+ g
.m
;
381 if ( (f
.m
^ sum
) & (g
.m
^ sum
) & Fix16_msb
)
386 inline Fix16
operator-(Fix16
& f
, Fix16
& g
)
388 short sum
= f
.m
- g
.m
;
389 if ( (f
.m
^ sum
) & (-g
.m
^ sum
) & Fix16_msb
)
394 inline Fix32
operator*(Fix16
& f
, Fix16
& g
)
396 return Fix32( long( long(f
.m
) * long(g
.m
) << 1));
399 inline Fix16
operator<<(Fix16
& a
, int b
)
404 inline Fix16
operator>>(Fix16
& a
, int b
)
409 inline Fix16
& Fix16:: operator+=(Fix16
& f
)
411 return *this = *this + f
;
414 inline Fix16
& Fix16:: operator-=(Fix16
& f
)
416 return *this = *this - f
;
419 inline Fix16
& Fix16::operator*=(Fix16
& f
)
421 return *this = *this * f
;
424 inline Fix16
& Fix16:: operator/=(Fix16
& f
)
426 return *this = *this / f
;
429 inline Fix16
& Fix16:: operator<<=(int b
)
431 return *this = *this << b
;
434 inline Fix16
& Fix16:: operator>>=(int b
)
436 return *this = *this >> b
;
439 inline int operator==(Fix16
& f
, Fix16
& g
)
444 inline int operator!=(Fix16
& f
, Fix16
& g
)
449 inline int operator>=(Fix16
& f
, Fix16
& g
)
454 inline int operator<=(Fix16
& f
, Fix16
& g
)
459 inline int operator>(Fix16
& f
, Fix16
& g
)
464 inline int operator<(Fix16
& f
, Fix16
& g
)
469 inline istream
& operator>>(istream
& s
, Fix16
& f
)
477 inline ostream
& operator<<(ostream
& s
, Fix16
& f
)
479 return s
<< double(f
);
483 inline Fix16
operator*(Fix16
& f
, int g
)
485 return Fix16(short(f
.m
* g
));
488 inline Fix16
operator*(int g
, Fix16
& f
)
494 inline Fix16
& Fix16::operator*=(int g
)
496 return *this = *this * g
;
499 inline Fix32::~Fix32() {}
501 inline long Fix32::round(double d
)
503 return long( (d
>= 0)? d
+ 0.5 : d
- 0.5);
507 inline long& mantissa(Fix32
& f
)
512 inline double value(Fix32
& f
)
517 inline Fix32
Fix32::operator+()
522 inline Fix32
Fix32::operator-()
527 inline Fix32
operator+(Fix32
& f
, Fix32
& g
)
529 long sum
= f
.m
+ g
.m
;
530 if ( (f
.m
^ sum
) & (g
.m
^ sum
) & Fix32_msb
)
535 inline Fix32
operator-(Fix32
& f
, Fix32
& g
)
537 long sum
= f
.m
- g
.m
;
538 if ( (f
.m
^ sum
) & (-g
.m
^ sum
) & Fix32_msb
)
543 inline Fix32
operator<<(Fix32
& a
, int b
)
548 inline Fix32
operator>>(Fix32
& a
, int b
)
553 inline Fix32
& Fix32::operator+=(Fix32
& f
)
555 return *this = *this + f
;
558 inline Fix32
& Fix32::operator-=(Fix32
& f
)
560 return *this = *this - f
;
563 inline Fix32
& Fix32::operator*=(Fix32
& f
)
565 return *this = *this * f
;
568 inline Fix32
& Fix32::operator/=(Fix32
& f
)
570 return *this = *this / f
;
574 inline Fix32
& Fix32::operator<<=(int b
)
576 return *this = *this << b
;
579 inline Fix32
& Fix32::operator>>=(int b
)
581 return *this = *this >> b
;
584 inline int operator==(Fix32
& f
, Fix32
& g
)
589 inline int operator!=(Fix32
& f
, Fix32
& g
)
594 inline int operator>=(Fix32
& f
, Fix32
& g
)
599 inline int operator<=(Fix32
& f
, Fix32
& g
)
604 inline int operator>(Fix32
& f
, Fix32
& g
)
609 inline int operator<(Fix32
& f
, Fix32
& g
)
614 inline istream
& operator>>(istream
& s
, Fix32
& f
)
622 inline ostream
& operator<<(ostream
& s
, Fix32
& f
)
624 return s
<< double(f
);
627 inline Fix32
operator*(Fix32
& f
, int g
)
629 return Fix32(long(f
.m
* g
));
632 inline Fix32
operator*(int g
, Fix32
& f
)
639 inline Fix32
& Fix32::operator*=(int g
)
641 return *this = *this * g
;