Sync usage with man page.
[netbsd-mini2440.git] / gnu / lib / libg++ / g++-include / Fix24.h
blobec48afcae6e158e1f29e726b488879fc10efb9f7
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)
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.
25 #ifndef _Fix24_h
26 #ifdef __GNUG__
27 #pragma once
28 #pragma interface
29 #endif
30 #define _Fix24_h 1
32 #include <stream.h>
33 #include <std.h>
35 // extra type definitions
37 typedef struct {
38 long u;
39 unsigned long l;
40 } twolongs;
42 // constant definitions
44 static const int
45 Fix24_shift = 31;
47 static const double
48 Fix24_fs = 2147483648., // 2^Fix24_shift
49 Fix24_mult = Fix24_fs,
50 Fix24_div = 1./Fix24_fs,
51 Fix24_max = 1. - .5/Fix24_fs,
52 Fix24_min = -1.;
54 static const unsigned long
55 Fix24_msb = 0x80000000L,
56 Fix24_lsb = 0x00000100L,
57 Fix24_m_max = 0x7fffff00L,
58 Fix24_m_min = 0x80000000L;
60 static const double
61 Fix48_fs = 36028797018963968., // 2^(24+Fix24_shift)
62 Fix48_max = 1. - .5/Fix48_fs,
63 Fix48_min = -1.,
64 Fix48_div_u = 1./Fix24_fs,
65 Fix48_div_l = 1./Fix48_fs;
67 static const twolongs
68 Fix48_msb = { 0x80000000L, 0L },
69 Fix48_lsb = { 0L, 0x00000100L },
70 Fix48_m_max = { 0x7fffff00L, 0xffffff00L },
71 Fix48_m_min = { 0x80000000L, 0L };
74 // Fix24 class: 24-bit Fixed point data type
76 // consists of a 24-bit mantissa (sign bit & 23 data bits).
79 class Fix24
81 friend class Fix48;
83 long m;
85 long assign(double d);
86 operator double();
87 Fix24(long i);
88 Fix24(int i);
91 public:
92 Fix24();
93 Fix24(Fix24& f);
94 Fix24(double d);
95 Fix24(Fix48& f);
97 ~Fix24();
99 Fix24& operator=(Fix24& f);
100 Fix24& operator=(double d);
101 Fix24& operator=(Fix48& f);
103 friend long& mantissa(Fix24& f);
104 friend double value(Fix24& f);
106 Fix24 operator + ();
107 Fix24 operator - ();
109 friend Fix24 operator + (Fix24& f, Fix24& g);
110 friend Fix24 operator - (Fix24& f, Fix24& g);
111 friend Fix48 operator * (Fix24& f, Fix24& g);
112 friend Fix24 operator * (Fix24& f, int g);
113 friend Fix24 operator * (int g, Fix24& f);
114 friend Fix24 operator / (Fix24& f, Fix24& g);
115 friend Fix24 operator << (Fix24& f, int b);
116 friend Fix24 operator >> (Fix24& f, int b);
118 Fix24& operator += (Fix24& f);
119 Fix24& operator -= (Fix24& f);
120 Fix24& operator *= (Fix24& f);
121 Fix24& operator *= (int b);
122 Fix24& operator /= (Fix24& f);
124 Fix24& operator <<=(int b);
125 Fix24& operator >>=(int b);
127 friend int operator == (Fix24& f, Fix24& g);
128 friend int operator != (Fix24& f, Fix24& g);
129 friend int operator >= (Fix24& f, Fix24& g);
130 friend int operator <= (Fix24& f, Fix24& g);
131 friend int operator > (Fix24& f, Fix24& g);
132 friend int operator < (Fix24& f, Fix24& g);
134 friend istream& operator >> (istream& s, Fix24& f);
135 friend ostream& operator << (ostream& s, Fix24& f);
137 void overflow(long&);
138 void range_error(long&);
143 // Fix48 class: 48-bit Fixed point data type
145 // consists of a 48-bit mantissa (sign bit & 47 data bits).
148 class Fix48
150 friend class Fix24;
152 twolongs m;
154 twolongs assign(double d);
155 operator double();
156 Fix48(twolongs i);
158 public:
159 Fix48();
160 Fix48(Fix48& f);
161 Fix48(Fix24& f);
162 Fix48(double d);
163 ~Fix48();
165 Fix48& operator = (Fix48& f);
166 Fix48& operator = (Fix24& f);
167 Fix48& operator = (double d);
169 friend twolongs& mantissa(Fix48& f);
170 friend double value(Fix48& f);
172 Fix48 operator + ();
173 Fix48 operator - ();
175 friend Fix48 operator + (Fix48& f, Fix48& g);
176 friend Fix48 operator - (Fix48& f, Fix48& g);
177 friend Fix48 operator * (Fix48& f, int g);
178 friend Fix48 operator * (int g, Fix48& f);
179 friend Fix48 operator << (Fix48& f, int b);
180 friend Fix48 operator >> (Fix48& f, int b);
182 friend Fix48 operator * (Fix24& f, Fix24& g);
184 Fix48& operator += (Fix48& f);
185 Fix48& operator -= (Fix48& f);
186 Fix48& operator *= (int b);
187 Fix48& operator <<=(int b);
188 Fix48& operator >>=(int b);
190 friend int operator == (Fix48& f, Fix48& g);
191 friend int operator != (Fix48& f, Fix48& g);
192 friend int operator >= (Fix48& f, Fix48& g);
193 friend int operator <= (Fix48& f, Fix48& g);
194 friend int operator > (Fix48& f, Fix48& g);
195 friend int operator < (Fix48& f, Fix48& g);
197 friend istream& operator >> (istream& s, Fix48& f);
198 friend ostream& operator << (ostream& s, Fix48& f);
200 void overflow(twolongs& i);
201 void range_error(twolongs& i);
205 // active error handler declarations
207 typedef void (*Fix24_peh)(long&);
208 typedef void (*Fix48_peh)(twolongs&);
210 extern Fix24_peh Fix24_overflow_handler;
211 extern Fix48_peh Fix48_overflow_handler;
213 extern Fix24_peh Fix24_range_error_handler;
214 extern Fix48_peh Fix48_range_error_handler;
217 // error handler declarations
219 #if defined(SHORT_NAMES) || defined(VMS)
220 #define set_overflow_handler sohndl
221 #define set_range_error_handler srnghdl
222 #endif
224 extern Fix24_peh set_Fix24_overflow_handler(Fix24_peh);
225 extern Fix48_peh set_Fix48_overflow_handler(Fix48_peh);
226 extern void set_overflow_handler(Fix24_peh, Fix48_peh);
228 extern Fix24_peh set_Fix24_range_error_handler(Fix24_peh);
229 extern Fix48_peh set_Fix48_range_error_handler(Fix48_peh);
230 extern void set_range_error_handler(Fix24_peh, Fix48_peh);
232 extern void
233 Fix24_ignore(long&),
234 Fix24_overflow_saturate(long&),
235 Fix24_overflow_warning_saturate(long&),
236 Fix24_warning(long&),
237 Fix24_abort(long&);
239 extern void
240 Fix48_ignore(twolongs&),
241 Fix48_overflow_saturate(twolongs&),
242 Fix48_overflow_warning_saturate(twolongs&),
243 Fix48_warning(twolongs&),
244 Fix48_abort(twolongs&);
246 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
248 inline Fix24::~Fix24() {}
250 inline Fix24::Fix24(long i)
252 m = i;
255 inline Fix24::Fix24(int i)
257 m = i;
260 inline Fix24::operator double()
262 return Fix24_div * m;
265 inline Fix24::Fix24()
267 m = 0;
270 inline Fix24::Fix24(Fix24& f)
272 m = f.m;
275 inline Fix24::Fix24(double d)
277 m = assign(d);
280 inline Fix24::Fix24(Fix48& f)
282 m = f.m.u;
285 inline Fix24& Fix24::operator=(Fix24& f)
287 m = f.m;
288 return *this;
291 inline Fix24& Fix24::operator=(double d)
293 m = assign(d);
294 return *this;
297 inline Fix24& Fix24::operator=(Fix48& f)
299 m = f.m.u;
300 return *this;
303 inline long& mantissa(Fix24& f)
305 return f.m;
308 inline double value(Fix24& f)
310 return double(f);
313 inline Fix24 Fix24::operator+()
315 return m;
318 inline Fix24 Fix24::operator-()
320 return -m;
323 inline Fix24 operator+(Fix24& f, Fix24& g)
325 long sum = f.m + g.m;
326 if ( (f.m ^ sum) & (g.m ^ sum) & Fix24_msb )
327 f.overflow(sum);
328 return sum;
331 inline Fix24 operator-(Fix24& f, Fix24& g)
333 long sum = f.m - g.m;
334 if ( (f.m ^ sum) & (-g.m ^ sum) & Fix24_msb )
335 f.overflow(sum);
336 return sum;
339 inline Fix24 operator*(Fix24& a, int b)
341 return a.m * b;
344 inline Fix24 operator*(int b, Fix24& a)
346 return a * b;
349 inline Fix24 operator<<(Fix24& a, int b)
351 return a.m << b;
354 inline Fix24 operator>>(Fix24& a, int b)
356 return (a.m >> b) & 0xffffff00L;
359 inline Fix24& Fix24:: operator+=(Fix24& f)
361 return *this = *this + f;
364 inline Fix24& Fix24:: operator-=(Fix24& f)
366 return *this = *this - f;
369 inline Fix24& Fix24::operator*=(Fix24& f)
371 return *this = *this * f;
374 inline Fix24& Fix24:: operator/=(Fix24& f)
376 return *this = *this / f;
379 inline Fix24& Fix24:: operator<<=(int b)
381 return *this = *this << b;
384 inline Fix24& Fix24:: operator>>=(int b)
386 return *this = *this >> b;
389 inline Fix24& Fix24::operator*=(int b)
391 return *this = *this * b;
394 inline int operator==(Fix24& f, Fix24& g)
396 return f.m == g.m;
399 inline int operator!=(Fix24& f, Fix24& g)
401 return f.m != g.m;
404 inline int operator>=(Fix24& f, Fix24& g)
406 return f.m >= g.m;
409 inline int operator<=(Fix24& f, Fix24& g)
411 return f.m <= g.m;
414 inline int operator>(Fix24& f, Fix24& g)
416 return f.m > g.m;
419 inline int operator<(Fix24& f, Fix24& g)
421 return f.m < g.m;
424 inline istream& operator>>(istream& s, Fix24& f)
426 double d;
427 s >> d;
428 f = d;
429 return s;
432 inline ostream& operator<<(ostream& s, Fix24& f)
434 return s << double(f);
437 inline Fix48::~Fix48() {}
439 inline Fix48::Fix48(twolongs i)
441 m = i;
444 inline Fix48:: operator double()
447 * Note: can't simply do Fix48_div_u * m.u + Fix48_div_l * m.l, because
448 * m.u is signed and m.l is unsigned.
450 return (m.u >= 0)? Fix48_div_u * m.u + Fix48_div_l * m.l :
451 (Fix48_div_u * ((unsigned long)(m.u & 0xffffff00))
452 + Fix48_div_l * m.l) - 2;
455 inline Fix48::Fix48()
457 m.u = 0;
458 m.l = 0;
461 inline Fix48::Fix48(Fix48& f)
463 m = f.m;
466 inline Fix48::Fix48(Fix24& f)
468 m.u = f.m;
469 m.l = 0;
472 inline Fix48::Fix48(double d)
474 m = assign(d);
477 inline Fix48& Fix48::operator=(Fix48& f)
479 m = f.m;
480 return *this;
483 inline Fix48& Fix48::operator=(Fix24& f)
485 m.u = f.m;
486 m.l = 0;
487 return *this;
490 inline Fix48& Fix48::operator=(double d)
492 m = assign(d);
493 return *this;
496 inline twolongs& mantissa(Fix48& f)
498 return f.m;
501 inline double value(Fix48& f)
503 return double(f);
506 inline Fix48 Fix48::operator+()
508 return m;
511 inline Fix48 Fix48::operator-()
513 twolongs n;
514 n.l = -m.l;
515 n.u = ~m.u + ((n.l ^ m.l) & Fix24_msb ? 0 : Fix24_lsb);
516 return Fix48(n);
519 inline Fix48 operator*(int b, Fix48& a)
521 return a * b;
524 inline Fix48& Fix48::operator+=(Fix48& f)
526 return *this = *this + f;
529 inline Fix48& Fix48::operator-=(Fix48& f)
531 return *this = *this - f;
534 inline Fix48& Fix48::operator*=(int b)
536 return *this = *this * b;
539 inline Fix48& Fix48::operator<<=(int b)
541 return *this = *this << b;
544 inline Fix48& Fix48::operator>>=(int b)
546 return *this = *this >> b;
549 inline int operator==(Fix48& f, Fix48& g)
551 return f.m.u == g.m.u && f.m.l == g.m.l;
554 inline int operator!=(Fix48& f, Fix48& g)
556 return f.m.u != g.m.u || f.m.l != g.m.l;
559 inline int operator>=(Fix48& f, Fix48& g)
561 return f.m.u >= g.m.u || (f.m.u == g.m.u && f.m.l >= g.m.l);
564 inline int operator<=(Fix48& f, Fix48& g)
566 return f.m.u <= g.m.u || (f.m.u == g.m.u && f.m.l <= g.m.l);
569 inline int operator>(Fix48& f, Fix48& g)
571 return f.m.u > g.m.u || (f.m.u == g.m.u && f.m.l > g.m.l);
574 inline int operator<(Fix48& f, Fix48& g)
576 return f.m.u < g.m.u || (f.m.u == g.m.u && f.m.l < g.m.l);
579 inline istream& operator>>(istream& s, Fix48& f)
581 double d;
582 s >> d;
583 f = d;
584 return s;
587 inline ostream& operator<<(ostream& s, Fix48& f)
589 return s << double(f);
593 #endif
594 #endif