xref: /386bsd/usr/include/nonstd/gnu/g++/Fix16.h (revision a2142627)
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