xref: /386bsd/usr/src/lib/libg++/g++-include/Rational.h (revision a2142627)
1 // This may look like C code, but it is really -*- C++ -*-
2 
3 /*
4 Copyright (C) 1988 Free Software Foundation
5     written 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 _Rational_h
26 #ifdef __GNUG__
27 #pragma once
28 #pragma interface
29 #endif
30 #define _Rational_h 1
31 
32 #include <Integer.h>
33 #include <math.h>
34 
35 class Rational
36 {
37 protected:
38   Integer          num;
39   Integer          den;
40 
41   void             normalize();
42 
43 public:
44                    Rational();
45                    Rational(double);
46                    Rational(long n, long d = 1);
47                    Rational(const Integer& n);
48                    Rational(const Integer& n, const Integer& d);
49                    Rational(const Rational&);
50 
51                   ~Rational();
52 
53   void             operator =  (const Rational& y);
54 
55   friend int       operator == (const Rational& x, const Rational& y);
56   friend int       operator != (const Rational& x, const Rational& y);
57   friend int       operator <  (const Rational& x, const Rational& y);
58   friend int       operator <= (const Rational& x, const Rational& y);
59   friend int       operator >  (const Rational& x, const Rational& y);
60   friend int       operator >= (const Rational& x, const Rational& y);
61 
62   friend Rational  operator +  (const Rational& x, const Rational& y);
63   friend Rational  operator -  (const Rational& x, const Rational& y);
64   friend Rational  operator *  (const Rational& x, const Rational& y);
65   friend Rational  operator /  (const Rational& x, const Rational& y);
66 
67   void             operator += (const Rational& y);
68   void             operator -= (const Rational& y);
69   void             operator *= (const Rational& y);
70   void             operator /= (const Rational& y);
71 
72 #ifdef __GNUG__
73   friend Rational  operator <? (const Rational& x, const Rational& y); // min
74   friend Rational  operator >? (const Rational& x, const Rational& y); // max
75 #endif
76 
77   friend Rational  operator - (const Rational& x);
78 
79 
80 // builtin Rational functions
81 
82 
83   void             negate();                      // x = -x
84   void             invert();                      // x = 1/x
85 
86   friend int       sign(const Rational& x);             // -1, 0, or +1
87   friend Rational  abs(const Rational& x);              // absolute value
88   friend Rational  sqr(const Rational& x);              // square
89   friend Rational  pow(const Rational& x, long y);
90   friend Rational  pow(const Rational& x, Integer& y);
91   const Integer&   numerator() const;
92   const Integer&   denominator() const;
93 
94 // coercion & conversion
95 
96                    operator double() const;
97   friend Integer   floor(const Rational& x);
98   friend Integer   ceil(const Rational& x);
99   friend Integer   trunc(const Rational& x);
100   friend Integer   round(const Rational& x);
101 
102   friend istream&  operator >> (istream& s, Rational& y);
103   friend ostream&  operator << (ostream& s, const Rational& y);
104 
105 
106 // procedural versions of operators
107 
108   friend int       compare(const Rational& x, const Rational& y);
109   friend void      add(const Rational& x, const Rational& y, Rational& dest);
110   friend void      sub(const Rational& x, const Rational& y, Rational& dest);
111   friend void      mul(const Rational& x, const Rational& y, Rational& dest);
112   friend void      div(const Rational& x, const Rational& y, Rational& dest);
113 
114 // error detection
115 
116   volatile void    error(const char* msg) const;
117   int              OK() const;
118 
119 };
120 
121 typedef Rational RatTmp; // backwards compatibility
122 
123 #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES)
124 
Rational()125 inline Rational::Rational()  {}
~Rational()126 inline Rational::~Rational() {}
127 
Rational(const Rational & y)128 inline Rational::Rational(const Rational& y) :num(y.num), den(y.den) {}
129 
Rational(const Integer & n)130 inline Rational::Rational(const Integer& n) :num(n), den(1) {}
131 
Rational(const Integer & n,const Integer & d)132 inline Rational::Rational(const Integer& n, const Integer& d) :num(n),den(d)
133 {
134   normalize();
135 }
136 
Rational(long n,long d)137 inline Rational::Rational(long n, long d) :num(n), den(d)
138 {
139   normalize();
140 }
141 
142 inline  void Rational::operator =  (const Rational& y)
143 {
144   num = y.num;  den = y.den;
145 }
146 
147 inline int operator == (const Rational& x, const Rational& y)
148 {
149   return compare(x.num, y.num) == 0 && compare(x.den, y.den) == 0;
150 }
151 
152 inline int operator != (const Rational& x, const Rational& y)
153 {
154   return compare(x.num, y.num) != 0 || compare(x.den, y.den) != 0;
155 }
156 
157 inline int operator <  (const Rational& x, const Rational& y)
158 {
159   return compare(x, y) <  0;
160 }
161 
162 inline int operator <= (const Rational& x, const Rational& y)
163 {
164   return compare(x, y) <= 0;
165 }
166 
167 inline int operator >  (const Rational& x, const Rational& y)
168 {
169   return compare(x, y) >  0;
170 }
171 
172 inline int operator >= (const Rational& x, const Rational& y)
173 {
174   return compare(x, y) >= 0;
175 }
176 
sign(const Rational & x)177 inline int sign(const Rational& x)
178 {
179   return sign(x.num);
180 }
181 
negate()182 inline void Rational::negate()
183 {
184   num.negate();
185 }
186 
187 
188 inline void Rational::operator += (const Rational& y)
189 {
190   add(*this, y, *this);
191 }
192 
193 inline void Rational::operator -= (const Rational& y)
194 {
195   sub(*this, y, *this);
196 }
197 
198 inline void Rational::operator *= (const Rational& y)
199 {
200   mul(*this, y, *this);
201 }
202 
203 inline void Rational::operator /= (const Rational& y)
204 {
205   div(*this, y, *this);
206 }
207 
numerator()208 inline const Integer& Rational::numerator() const { return num; }
denominator()209 inline const Integer& Rational::denominator() const { return den; }
210 inline Rational::operator double() const { return ratio(num, den); }
211 
212 #ifdef __GNUG__
213 inline Rational operator <? (const Rational& x, const Rational& y)
214 {
215   if (compare(x, y) <= 0) return x; else return y;
216 }
217 
218 inline Rational operator >? (const Rational& x, const Rational& y)
219 {
220   if (compare(x, y) >= 0) return x; else return y;
221 }
222 #endif
223 
224 #if defined(__GNUG__) && !defined(NO_NRV)
225 
226 inline Rational operator + (const Rational& x, const Rational& y) return r
227 {
228   add(x, y, r);
229 }
230 
231 inline Rational operator - (const Rational& x, const Rational& y) return r
232 {
233   sub(x, y, r);
234 }
235 
236 inline Rational operator * (const Rational& x, const Rational& y) return r
237 {
238   mul(x, y, r);
239 }
240 
241 inline Rational operator / (const Rational& x, const Rational& y) return r
242 {
243   div(x, y, r);
244 }
245 
246 #else /* NO_NRV */
247 
248 inline Rational operator + (const Rational& x, const Rational& y)
249 {
250   Rational r; add(x, y, r); return r;
251 }
252 
253 inline Rational operator - (const Rational& x, const Rational& y)
254 {
255   Rational r; sub(x, y, r); return r;
256 }
257 
258 inline Rational operator * (const Rational& x, const Rational& y)
259 {
260   Rational r; mul(x, y, r); return r;
261 }
262 
263 inline Rational operator / (const Rational& x, const Rational& y)
264 {
265   Rational r; div(x, y, r); return r;
266 }
267 #endif
268 #endif
269 
270 #endif
271