Sync usage with man page.
[netbsd-mini2440.git] / gnu / lib / libg++ / g++-include / Fix.h
blobd325228ce51ff77825c4d66c35a2de2d392a7bc8
1 //
2 // Fix.h : variable length fixed point data type
3 //
5 #ifndef _Fix_h
6 #ifdef __GNUG__
7 #pragma once
8 #pragma interface
9 #endif
10 #define _Fix_h 1
12 #include <stream.h>
13 #include <std.h>
14 #include <stddef.h>
15 #include <Integer.h>
17 typedef unsigned short uint16;
18 typedef short int16;
19 typedef unsigned long uint32;
20 typedef long int32;
22 #define _Fix_min_length 1
23 #define _Fix_max_length 65535
25 #define _Fix_min_value -1.0
26 #define _Fix_max_value 1.0
28 extern uint16 Fix_default_length;
29 extern int Fix_default_print_width;
31 struct _Frep // internal Fix representation
33 uint16 len; // length in bits
34 uint16 siz; // allocated storage
35 int16 ref; // reference count
36 uint16 s[1]; // start of ushort array represention
39 typedef struct _Frep* _Fix;
41 extern _Frep _Frep_0;
42 extern _Frep _Frep_m1;
43 extern _Frep _Frep_quotient_bump;
45 class Fix
47 _Fix rep;
49 Fix(_Fix);
51 void unique();
53 public:
54 Fix();
55 Fix(Fix&);
56 Fix(double&);
57 Fix(int);
58 Fix(int, Fix&);
59 Fix(int, double&);
60 Fix(int, _Frep*);
62 ~Fix();
64 Fix operator = (Fix&);
65 Fix operator = (double&);
67 friend int operator == (Fix&, Fix& );
68 friend int operator != (Fix&, Fix&);
70 friend int operator < (Fix&, Fix&);
71 friend int operator <= (Fix&, Fix&);
72 friend int operator > (Fix&, Fix&);
73 friend int operator >= (Fix&, Fix&);
75 Fix& operator + ();
76 Fix operator - ();
78 friend Fix operator + (Fix&, Fix&);
79 friend Fix operator - (Fix&, Fix&);
80 friend Fix operator * (Fix&, Fix&);
81 friend Fix operator / (Fix&, Fix&);
83 friend Fix operator * (Fix&, int);
84 friend Fix operator * (int, Fix&);
85 friend Fix operator % (Fix&, int);
86 friend Fix operator << (Fix&, int);
87 friend Fix operator >> (Fix&, int);
89 #ifdef __GNUG__
90 friend Fix operator <? (Fix&, Fix&); // min
91 friend Fix operator >? (Fix&, Fix&); // max
92 #endif
94 Fix operator += (Fix&);
95 Fix operator -= (Fix&);
96 Fix operator *= (Fix&);
97 Fix operator /= (Fix&);
99 Fix operator *= (int);
100 Fix operator %= (int);
101 Fix operator <<=(int);
102 Fix operator >>=(int);
104 friend char* Ftoa(Fix&, int width = Fix_default_print_width);
105 friend Fix atoF(const char*, int len = Fix_default_length);
107 friend istream& operator >> (istream&, Fix&);
108 friend ostream& operator << (ostream&, Fix&);
110 // built-in functions
111 friend Fix abs(Fix); // absolute value
112 friend int sgn(Fix&); // -1, 0, +1
113 friend Integer mantissa(Fix&); // integer representation
114 friend double value(Fix&); // double value
115 friend int length(Fix&); // field length
116 friend void show(Fix&); // show contents
118 // error handlers
119 void error(const char* msg); // error handler
120 void range_error(const char* msg); // range error handler
122 // internal class functions
123 friend void mask(_Fix);
124 friend int compare(_Fix, _Fix = &_Frep_0);
126 friend _Fix new_Fix(uint16);
127 friend _Fix new_Fix(uint16, _Fix);
128 friend _Fix new_Fix(uint16, double);
130 friend _Fix copy(_Fix, _Fix);
131 friend _Fix negate(_Fix, _Fix = NULL);
132 friend _Fix add(_Fix, _Fix, _Fix = NULL);
133 friend _Fix subtract(_Fix, _Fix, _Fix = NULL);
134 friend _Fix multiply(_Fix, _Fix, _Fix = NULL);
135 friend _Fix multiply(_Fix, int, _Fix = NULL);
136 friend _Fix divide(_Fix, _Fix, _Fix = NULL, _Fix = NULL);
137 friend _Fix shift(_Fix, int, _Fix = NULL);
139 // non-operator versions for user
140 friend void negate(Fix& x, Fix& r);
141 friend void add(Fix& x, Fix& y, Fix& r);
142 friend void subtract(Fix& x, Fix& y, Fix& r);
143 friend void multiply(Fix& x, Fix& y, Fix& r);
144 friend void divide(Fix& x, Fix& y, Fix& q, Fix& r);
145 friend void shift(Fix& x, int y, Fix& r);
148 // error handlers
150 extern void
151 default_Fix_error_handler(const char*),
152 default_Fix_range_error_handler(const char*);
154 extern one_arg_error_handler_t
155 Fix_error_handler,
156 Fix_range_error_handler;
158 extern one_arg_error_handler_t
159 set_Fix_error_handler(one_arg_error_handler_t f),
160 set_Fix_range_error_handler(one_arg_error_handler_t f);
162 typedef void (*Fix_peh)(_Fix&);
163 extern Fix_peh Fix_overflow_handler;
165 extern void
166 Fix_overflow_saturate(_Fix&),
167 Fix_overflow_wrap(_Fix&),
168 Fix_overflow_warning_saturate(_Fix&),
169 Fix_overflow_warning(_Fix&),
170 Fix_overflow_error(_Fix&);
172 extern Fix_peh set_overflow_handler(Fix_peh);
174 extern int Fix_set_default_length(int);
176 // function definitions
178 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
180 inline void Fix::unique()
182 if ( rep->ref > 1 )
184 rep->ref--;
185 rep = new_Fix(rep->len,rep);
189 inline void mask (_Fix x)
191 int n = x->len & 0x0f;
192 if ( n )
193 x->s[x->siz - 1] &= 0xffff0000 >> n;
196 inline _Fix copy(_Fix from, _Fix to)
198 uint16 *ts = to->s, *fs = from->s;
199 int ilim = to->siz < from->siz ? to->siz : from->siz;
200 for ( int i=0; i < ilim; i++ )
201 *ts++ = *fs++;
202 for ( ; i < to->siz; i++ )
203 *ts++ = 0;
204 mask(to);
205 return to;
208 inline Fix::Fix(_Fix f)
210 rep = f;
213 inline Fix::Fix()
215 rep = new_Fix(Fix_default_length);
218 inline Fix::Fix(int len)
220 if ( len < _Fix_min_length || len > _Fix_max_length )
221 error("illegal length in declaration");
222 rep = new_Fix((uint16 )len);
225 inline Fix::Fix(double& d)
227 rep = new_Fix(Fix_default_length,d);
230 inline Fix::Fix(Fix& y)
232 rep = y.rep; rep->ref++;
235 inline Fix::Fix(int len, Fix& y)
237 if ( len < _Fix_min_length || len > _Fix_max_length )
238 error("illegal length in declaration");
239 rep = new_Fix((uint16 )len,y.rep);
242 inline Fix::Fix(int len, _Frep* fr)
244 if ( len < 1 || len > 65535 )
245 error("illegal length in declaration");
246 rep = new_Fix((uint16 )len,fr);
249 inline Fix::Fix(int len, double& d)
251 if ( len < _Fix_min_length || len > _Fix_max_length )
252 error("illegal length in declaration");
253 rep = new_Fix((uint16 )len,d);
256 inline Fix::~Fix()
258 if ( --rep->ref <= 0 ) delete rep;
261 inline Fix Fix::operator = (Fix& y)
263 if ( rep->len == y.rep->len ) {
264 ++y.rep->ref;
265 if ( --rep->ref <= 0 ) delete rep;
266 rep = y.rep;
268 else {
269 unique();
270 copy(y.rep,rep);
272 return *this;
275 inline Fix Fix::operator = (double& d)
277 int oldlen = rep->len;
278 if ( --rep->ref <= 0 ) delete rep;
279 rep = new_Fix(oldlen,d);
280 return *this;
283 inline int operator == (Fix& x, Fix& y)
285 return compare(x.rep, y.rep) == 0;
288 inline int operator != (Fix& x, Fix& y)
290 return compare(x.rep, y.rep) != 0;
293 inline int operator < (Fix& x, Fix& y)
295 return compare(x.rep, y.rep) < 0;
298 inline int operator <= (Fix& x, Fix& y)
300 return compare(x.rep, y.rep) <= 0;
303 inline int operator > (Fix& x, Fix& y)
305 return compare(x.rep, y.rep) > 0;
308 inline int operator >= (Fix& x, Fix& y)
310 return compare(x.rep, y.rep) >= 0;
313 inline Fix& Fix::operator + ()
315 return *this;
318 inline Fix Fix::operator - ()
320 _Fix r = negate(rep); return r;
323 inline Fix operator + (Fix& x, Fix& y)
325 _Fix r = add(x.rep, y.rep); return r;
328 inline Fix operator - (Fix& x, Fix& y)
330 _Fix r = subtract(x.rep, y.rep); return r;
333 inline Fix operator * (Fix& x, Fix& y)
335 _Fix r = multiply(x.rep, y.rep); return r;
338 inline Fix operator * (Fix& x, int y)
340 _Fix r = multiply(x.rep, y); return r;
343 inline Fix operator * (int y, Fix& x)
345 _Fix r = multiply(x.rep, y); return r;
348 inline Fix operator / (Fix& x, Fix& y)
350 _Fix r = divide(x.rep, y.rep); return r;
353 inline Fix Fix::operator += (Fix& y)
355 unique(); add(rep, y.rep, rep); return *this;
358 inline Fix Fix::operator -= (Fix& y)
360 unique(); subtract(rep, y.rep, rep); return *this;
363 inline Fix Fix::operator *= (Fix& y)
365 unique(); multiply(rep, y.rep, rep); return *this;
368 inline Fix Fix::operator *= (int y)
370 unique(); multiply(rep, y, rep); return *this;
373 inline Fix Fix::operator /= (Fix& y)
375 unique(); divide(rep, y.rep, rep); return *this;
378 inline Fix operator % (Fix& x, int y)
380 Fix r((int )x.rep->len + y, x); return r;
383 inline Fix operator << (Fix& x, int y)
385 _Fix rep = shift(x.rep, y); return rep;
388 inline Fix operator >> (Fix& x, int y)
390 _Fix rep = shift(x.rep, -y); return rep;
393 inline Fix Fix::operator <<= (int y)
395 unique(); shift(rep, y, rep); return *this;
398 inline Fix Fix::operator >>= (int y)
400 unique(); shift(rep, -y, rep); return *this;
403 #ifdef __GNUG__
404 inline Fix operator <? (Fix& x, Fix& y)
406 if ( compare(x.rep, y.rep) <= 0 ) return x; else return y;
409 inline Fix operator >? (Fix& x, Fix& y)
411 if ( compare(x.rep, y.rep) >= 0 ) return x; else return y;
413 #endif
415 inline Fix abs(Fix x)
417 _Fix r = (compare(x.rep) >= 0 ? new_Fix(x.rep->len,x.rep) : negate(x.rep));
418 return r;
421 inline int sgn(Fix& x)
423 int a = compare(x.rep);
424 return a == 0 ? 0 : (a > 0 ? 1 : -1);
427 inline int length(Fix& x)
429 return x.rep->len;
432 inline ostream& operator << (ostream& s, Fix& y)
434 return s << Ftoa(y);
437 inline void negate (Fix& x, Fix& r)
439 negate(x.rep, r.rep);
442 inline void add (Fix& x, Fix& y, Fix& r)
444 add(x.rep, y.rep, r.rep);
447 inline void subtract (Fix& x, Fix& y, Fix& r)
449 subtract(x.rep, y.rep, r.rep);
452 inline void multiply (Fix& x, Fix& y, Fix& r)
454 multiply(x.rep, y.rep, r.rep);
457 inline void divide (Fix& x, Fix& y, Fix& q, Fix& r)
459 divide(x.rep, y.rep, q.rep, r.rep);
462 inline void shift (Fix& x, int y, Fix& r)
464 shift(x.rep, y, r.rep);
467 #endif
468 #endif