1 // This may look like C code, but it is really -*- C++ -*-
2 /*
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)
6
7 This file is part of GNU CC.
8
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.
15
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.
23 */
24
25 #ifndef _Fix16_h
26 #ifdef __GNUG__
27 #pragma once
28 #pragma interface
29 #endif
30 #define _Fix16_h 1
31
32 #include <stream.h>
33 #include <std.h>
34
35 // constant definitions
36
37 #define Fix16_fs ((double)((unsigned)(1 << 15)))
38
39 #define Fix16_msb (1 << 15)
40 #define Fix16_m_max ((1 << 15) - 1)
41 #define Fix16_m_min ((short)(1 << 15))
42
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.)
47
48
49 #define Fix32_fs ((double)((unsigned long)(1 << 31)))
50
51 #define Fix32_msb ((unsigned long)(1 << 31))
52 #define Fix32_m_max ((1 << 31) - 1)
53 #define Fix32_m_min ((long)(1 << 31))
54
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.)
59
60
61 //
62 // Fix16 class: 16-bit Fixed point data type
63 //
64 // consists of a 16-bit mantissa (sign bit & 15 data bits).
65 //
66
67 class Fix16
68 {
69 friend class Fix32;
70
71 short m;
72
73 short round(double d);
74 short assign(double d);
75 Fix16(short i);
76 Fix16(int i);
77
78 operator double();
79
80
81 public:
82 Fix16();
83 Fix16(Fix16& f);
84 Fix16(double d);
85 Fix16(Fix32& f);
86
87 ~Fix16();
88
89 Fix16& operator=(Fix16& f);
90 Fix16& operator=(double d);
91 Fix16& operator=(Fix32& f);
92
93 friend short& mantissa(Fix16& f);
94 friend double value(Fix16& f);
95
96 Fix16 operator + ();
97 Fix16 operator - ();
98
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);
105
106 Fix16& operator += (Fix16& f);
107 Fix16& operator -= (Fix16& f);
108 Fix16& operator *= (Fix16& );
109 Fix16& operator /= (Fix16& f);
110
111 Fix16& operator <<=(int b);
112 Fix16& operator >>=(int b);
113
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);
120
121 friend istream& operator >> (istream& s, Fix16& f);
122 friend ostream& operator << (ostream& s, Fix16& f);
123
124 void overflow(short&);
125 void range_error(short&);
126
127 friend Fix16 operator * (Fix16& f, int g);
128 friend Fix16 operator * (int g, Fix16& f);
129 Fix16& operator *= (int g);
130 };
131
132
133 //
134 // Fix32 class: 32-bit Fixed point data type
135 //
136 // consists of a 32-bit mantissa (sign bit & 31 data bits).
137 //
138
139 class Fix32
140 {
141 friend class Fix16;
142
143 long m;
144
145 long round(double d);
146 long assign(double d);
147
148 Fix32(long i);
149 operator double();
150
151
152 public:
153 Fix32();
154 Fix32(Fix32& f);
155 Fix32(Fix16& f);
156 Fix32(double d);
157 ~Fix32();
158
159 Fix32& operator = (Fix32& f);
160 Fix32& operator = (Fix16& f);
161 Fix32& operator = (double d);
162
163 friend long& mantissa(Fix32& f);
164 friend double value(Fix32& f);
165
166 Fix32 operator + ();
167 Fix32 operator - ();
168
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);
175
176 friend Fix32 operator * (Fix16& f, Fix16& g);
177
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);
184
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);
191
192 friend istream& operator >> (istream& s, Fix32& f);
193 friend ostream& operator << (ostream& s, Fix32& f);
194
195 void overflow(long& i);
196 void range_error(long& i);
197
198 friend Fix32 operator * (Fix32& f, int g);
199 friend Fix32 operator * (int g, Fix32& f);
200 Fix32& operator *= (int g);
201 };
202
203 // active error handler declarations
204
205 typedef void (*Fix16_peh)(short&);
206 typedef void (*Fix32_peh)(long&);
207
208 extern Fix16_peh Fix16_overflow_handler;
209 extern Fix32_peh Fix32_overflow_handler;
210
211 extern Fix16_peh Fix16_range_error_handler;
212 extern Fix32_peh Fix32_range_error_handler;
213
214 #if defined(SHORT_NAMES) || defined(VMS)
215 #define set_overflow_handler sohndl
216 #define set_range_error_handler srnghdl
217 #endif
218
219
220 // error handler declarations
221
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);
225
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);
229
230 extern void
231 Fix16_ignore(short&),
232 Fix16_overflow_saturate(short&),
233 Fix16_overflow_warning_saturate(short&),
234 Fix16_warning(short&),
235 Fix16_abort(short&);
236
237 extern void
238 Fix32_ignore(long&),
239 Fix32_overflow_saturate(long&),
240 Fix32_overflow_warning_saturate(long&),
241 Fix32_warning(long&),
242 Fix32_abort(long&);
243
244 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
245
~Fix16()246 inline Fix16::~Fix16() {}
247
round(double d)248 inline short Fix16::round(double d)
249 {
250 return short( (d >= 0)? d + 0.5 : d - 0.5);
251 }
252
Fix16(short i)253 inline Fix16::Fix16(short i)
254 {
255 m = i;
256 }
257
Fix16(int i)258 inline Fix16::Fix16(int i)
259 {
260 m = i;
261 }
262
263 inline Fix16::operator double()
264 {
265 return Fix16_div * m;
266 }
267
Fix16()268 inline Fix16::Fix16()
269 {
270 m = 0;
271 }
272
Fix16(Fix16 & f)273 inline Fix16::Fix16(Fix16& f)
274 {
275 m = f.m;
276 }
277
Fix16(double d)278 inline Fix16::Fix16(double d)
279 {
280 m = assign(d);
281 }
282
283
284 inline Fix16& Fix16::operator=(Fix16& f)
285 {
286 m = f.m;
287 return *this;
288 }
289
290 inline Fix16& Fix16::operator=(double d)
291 {
292 m = assign(d);
293 return *this;
294 }
295
296
Fix32()297 inline Fix32::Fix32()
298 {
299 m = 0;
300 }
301
Fix32(long i)302 inline Fix32::Fix32(long i)
303 {
304 m = i;
305 }
306
307 inline Fix32:: operator double()
308 {
309 return Fix32_div * m;
310 }
311
312
Fix32(Fix32 & f)313 inline Fix32::Fix32(Fix32& f)
314 {
315 m = f.m;
316 }
317
Fix32(Fix16 & f)318 inline Fix32::Fix32(Fix16& f)
319 {
320 m = long(f.m) << 16;
321 }
322
Fix32(double d)323 inline Fix32::Fix32(double d)
324 {
325 m = assign(d);
326 }
327
Fix16(Fix32 & f)328 inline Fix16::Fix16(Fix32& f)
329 {
330 m = f.m >> 16;
331 }
332
333
334 inline Fix16& Fix16::operator=(Fix32& f)
335 {
336 m = f.m >> 16;
337 return *this;
338 }
339
340 inline Fix32& Fix32::operator=(Fix32& f)
341 {
342 m = f.m;
343 return *this;
344 }
345
346 inline Fix32& Fix32::operator=(Fix16& f)
347 {
348 m = long(f.m) << 16;
349 return *this;
350 }
351
352 inline Fix32& Fix32::operator=(double d)
353 {
354 m = assign(d);
355 return *this;
356 }
357
mantissa(Fix16 & f)358 inline short& mantissa(Fix16& f)
359 {
360 return f.m;
361 }
362
value(Fix16 & f)363 inline double value(Fix16& f)
364 {
365 return double(f);
366 }
367
368 inline Fix16 Fix16::operator+()
369 {
370 return m;
371 }
372
373 inline Fix16 Fix16::operator-()
374 {
375 return -m;
376 }
377
378 inline Fix16 operator+(Fix16& f, Fix16& g)
379 {
380 short sum = f.m + g.m;
381 if ( (f.m ^ sum) & (g.m ^ sum) & Fix16_msb )
382 f.overflow(sum);
383 return sum;
384 }
385
386 inline Fix16 operator-(Fix16& f, Fix16& g)
387 {
388 short sum = f.m - g.m;
389 if ( (f.m ^ sum) & (-g.m ^ sum) & Fix16_msb )
390 f.overflow(sum);
391 return sum;
392 }
393
394 inline Fix32 operator*(Fix16& f, Fix16& g)
395 {
396 return Fix32( long( long(f.m) * long(g.m) << 1));
397 }
398
399 inline Fix16 operator<<(Fix16& a, int b)
400 {
401 return a.m << b;
402 }
403
404 inline Fix16 operator>>(Fix16& a, int b)
405 {
406 return a.m >> b;
407 }
408
409 inline Fix16& Fix16:: operator+=(Fix16& f)
410 {
411 return *this = *this + f;
412 }
413
414 inline Fix16& Fix16:: operator-=(Fix16& f)
415 {
416 return *this = *this - f;
417 }
418
419 inline Fix16& Fix16::operator*=(Fix16& f)
420 {
421 return *this = *this * f;
422 }
423
424 inline Fix16& Fix16:: operator/=(Fix16& f)
425 {
426 return *this = *this / f;
427 }
428
429 inline Fix16& Fix16:: operator<<=(int b)
430 {
431 return *this = *this << b;
432 }
433
434 inline Fix16& Fix16:: operator>>=(int b)
435 {
436 return *this = *this >> b;
437 }
438
439 inline int operator==(Fix16& f, Fix16& g)
440 {
441 return f.m == g.m;
442 }
443
444 inline int operator!=(Fix16& f, Fix16& g)
445 {
446 return f.m != g.m;
447 }
448
449 inline int operator>=(Fix16& f, Fix16& g)
450 {
451 return f.m >= g.m;
452 }
453
454 inline int operator<=(Fix16& f, Fix16& g)
455 {
456 return f.m <= g.m;
457 }
458
459 inline int operator>(Fix16& f, Fix16& g)
460 {
461 return f.m > g.m;
462 }
463
464 inline int operator<(Fix16& f, Fix16& g)
465 {
466 return f.m < g.m;
467 }
468
469 inline istream& operator>>(istream& s, Fix16& f)
470 {
471 double d;
472 s >> d;
473 f = d;
474 return s;
475 }
476
477 inline ostream& operator<<(ostream& s, Fix16& f)
478 {
479 return s << double(f);
480 }
481
482
483 inline Fix16 operator*(Fix16& f, int g)
484 {
485 return Fix16(short(f.m * g));
486 }
487
488 inline Fix16 operator*(int g, Fix16& f)
489 {
490 return f * g;
491 }
492
493
494 inline Fix16& Fix16::operator*=(int g)
495 {
496 return *this = *this * g;
497 }
498
~Fix32()499 inline Fix32::~Fix32() {}
500
round(double d)501 inline long Fix32::round(double d)
502 {
503 return long( (d >= 0)? d + 0.5 : d - 0.5);
504 }
505
506
mantissa(Fix32 & f)507 inline long& mantissa(Fix32& f)
508 {
509 return f.m;
510 }
511
value(Fix32 & f)512 inline double value(Fix32& f)
513 {
514 return double(f);
515 }
516
517 inline Fix32 Fix32::operator+()
518 {
519 return m;
520 }
521
522 inline Fix32 Fix32::operator-()
523 {
524 return -m;
525 }
526
527 inline Fix32 operator+(Fix32& f, Fix32& g)
528 {
529 long sum = f.m + g.m;
530 if ( (f.m ^ sum) & (g.m ^ sum) & Fix32_msb )
531 f.overflow(sum);
532 return sum;
533 }
534
535 inline Fix32 operator-(Fix32& f, Fix32& g)
536 {
537 long sum = f.m - g.m;
538 if ( (f.m ^ sum) & (-g.m ^ sum) & Fix32_msb )
539 f.overflow(sum);
540 return sum;
541 }
542
543 inline Fix32 operator<<(Fix32& a, int b)
544 {
545 return a.m << b;
546 }
547
548 inline Fix32 operator>>(Fix32& a, int b)
549 {
550 return a.m >> b;
551 }
552
553 inline Fix32& Fix32::operator+=(Fix32& f)
554 {
555 return *this = *this + f;
556 }
557
558 inline Fix32& Fix32::operator-=(Fix32& f)
559 {
560 return *this = *this - f;
561 }
562
563 inline Fix32& Fix32::operator*=(Fix32& f)
564 {
565 return *this = *this * f;
566 }
567
568 inline Fix32& Fix32::operator/=(Fix32& f)
569 {
570 return *this = *this / f;
571 }
572
573
574 inline Fix32& Fix32::operator<<=(int b)
575 {
576 return *this = *this << b;
577 }
578
579 inline Fix32& Fix32::operator>>=(int b)
580 {
581 return *this = *this >> b;
582 }
583
584 inline int operator==(Fix32& f, Fix32& g)
585 {
586 return f.m == g.m;
587 }
588
589 inline int operator!=(Fix32& f, Fix32& g)
590 {
591 return f.m != g.m;
592 }
593
594 inline int operator>=(Fix32& f, Fix32& g)
595 {
596 return f.m >= g.m;
597 }
598
599 inline int operator<=(Fix32& f, Fix32& g)
600 {
601 return f.m <= g.m;
602 }
603
604 inline int operator>(Fix32& f, Fix32& g)
605 {
606 return f.m > g.m;
607 }
608
609 inline int operator<(Fix32& f, Fix32& g)
610 {
611 return f.m < g.m;
612 }
613
614 inline istream& operator>>(istream& s, Fix32& f)
615 {
616 double d;
617 s >> d;
618 f = d;
619 return s;
620 }
621
622 inline ostream& operator<<(ostream& s, Fix32& f)
623 {
624 return s << double(f);
625 }
626
627 inline Fix32 operator*(Fix32& f, int g)
628 {
629 return Fix32(long(f.m * g));
630 }
631
632 inline Fix32 operator*(int g, Fix32& f)
633 {
634 return f * g;
635 }
636
637
638
639 inline Fix32& Fix32::operator*=(int g)
640 {
641 return *this = *this * g;
642 }
643
644
645 #endif
646 #endif
647
648