home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Headers / g++ / Rational.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  7.8 KB  |  286 lines

  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 the GNU C++ Library.  This library is free
  8. software; you can redistribute it and/or modify it under the terms of
  9. the GNU Library General Public License as published by the Free
  10. Software Foundation; either version 2 of the License, or (at your
  11. option) any later version.  This library is distributed in the hope
  12. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  13. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14. PURPOSE.  See the GNU Library General Public License for more details.
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #ifndef _Rational_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #pragma cplusplus
  24. #endif
  25. #define _Rational_h 1
  26.  
  27. #include <Integer.h>
  28. extern "C" {
  29. #include <math.h>
  30. }
  31. class Rational
  32. {
  33. protected:
  34.   Integer          num;
  35.   Integer          den;
  36.  
  37.   void             normalize();
  38.  
  39. public:
  40.                    Rational();
  41.                    Rational(double);
  42.                    Rational(int n);
  43.                    Rational(long n);
  44.                    Rational(int n, int d);
  45.                    Rational(long n, long d);
  46.                    Rational(long n, unsigned long d);
  47.                    Rational(unsigned long n, long d);
  48.                    Rational(unsigned long n, unsigned long d);
  49.                    Rational(const Integer& n);
  50.                    Rational(const Integer& n, const Integer& d);
  51.                    Rational(const Rational&);
  52.  
  53.                   ~Rational();
  54.  
  55.   void             operator =  (const Rational& y);
  56.  
  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.   friend int       operator >  (const Rational& x, const Rational& y);
  62.   friend int       operator >= (const Rational& x, const Rational& y);
  63.  
  64.   friend Rational  operator +  (const Rational& x, const Rational& y);
  65.   friend Rational  operator -  (const Rational& x, const Rational& y);
  66.   friend Rational  operator *  (const Rational& x, const Rational& y);
  67.   friend Rational  operator /  (const Rational& x, const Rational& y);
  68.  
  69.   void             operator += (const Rational& y);
  70.   void             operator -= (const Rational& y);
  71.   void             operator *= (const Rational& y);
  72.   void             operator /= (const Rational& y);
  73.  
  74. #ifdef __GNUG__
  75.   friend Rational  operator <? (const Rational& x, const Rational& y); // min
  76.   friend Rational  operator >? (const Rational& x, const Rational& y); // max
  77. #endif
  78.  
  79.   friend Rational  operator - (const Rational& x);
  80.  
  81.  
  82. // builtin Rational functions
  83.  
  84.  
  85.   void             negate();                      // x = -x
  86.   void             invert();                      // x = 1/x
  87.  
  88.   friend int       sign(const Rational& x);             // -1, 0, or +1
  89.   friend Rational  abs(const Rational& x);              // absolute value
  90.   friend Rational  sqr(const Rational& x);              // square
  91.   friend Rational  pow(const Rational& x, long y);
  92.   friend Rational  pow(const Rational& x, const Integer& y);
  93.   const Integer&   numerator() const;
  94.   const Integer&   denominator() const;
  95.  
  96. // coercion & conversion
  97.  
  98.                    operator double() const;
  99.   friend Integer   floor(const Rational& x);
  100.   friend Integer   ceil(const Rational& x);
  101.   friend Integer   trunc(const Rational& x);
  102.   friend Integer   round(const Rational& x);
  103.  
  104.   friend istream&  operator >> (istream& s, Rational& y);
  105.   friend ostream&  operator << (ostream& s, const Rational& y);
  106.  
  107.   int           fits_in_float() const;
  108.   int           fits_in_double() const;
  109.  
  110. // procedural versions of operators
  111.  
  112.   friend int       compare(const Rational& x, const Rational& y);
  113.   friend void      add(const Rational& x, const Rational& y, Rational& dest);
  114.   friend void      sub(const Rational& x, const Rational& y, Rational& dest);
  115.   friend void      mul(const Rational& x, const Rational& y, Rational& dest);
  116.   friend void      div(const Rational& x, const Rational& y, Rational& dest);
  117.  
  118. // error detection
  119.  
  120.   void    error(const char* msg) const;
  121.   int              OK() const;
  122.  
  123. };
  124.  
  125. typedef Rational RatTmp; // backwards compatibility
  126.  
  127. inline Rational::Rational() : num(&_ZeroRep), den(&_OneRep) {}
  128. inline Rational::~Rational() {}
  129.  
  130. inline Rational::Rational(const Rational& y) :num(y.num), den(y.den) {}
  131.  
  132. inline Rational::Rational(const Integer& n) :num(n), den(&_OneRep) {}
  133.  
  134. inline Rational::Rational(const Integer& n, const Integer& d) :num(n),den(d)
  135. {
  136.   normalize();
  137. }
  138.  
  139. inline Rational::Rational(long n) :num(n), den(&_OneRep) { }
  140.  
  141. inline Rational::Rational(int n) :num(n), den(&_OneRep) { }
  142.  
  143. inline Rational::Rational(long n, long d) :num(n), den(d) { normalize(); }
  144. inline Rational::Rational(int n, int d) :num(n), den(d) { normalize(); }
  145. inline Rational::Rational(long n, unsigned long d) :num(n), den(d)
  146. {
  147.   normalize();
  148. }
  149. inline Rational::Rational(unsigned long n, long d) :num(n), den(d)
  150. {
  151.   normalize();
  152. }
  153. inline Rational::Rational(unsigned long n, unsigned long d) :num(n), den(d)
  154. {
  155.   normalize();
  156. }
  157.  
  158. inline  void Rational::operator =  (const Rational& y)
  159. {
  160.   num = y.num;  den = y.den;
  161. }
  162.  
  163. inline int operator == (const Rational& x, const Rational& y)
  164. {
  165.   return compare(x.num, y.num) == 0 && compare(x.den, y.den) == 0;
  166. }
  167.  
  168. inline int operator != (const Rational& x, const Rational& y)
  169. {
  170.   return compare(x.num, y.num) != 0 || compare(x.den, y.den) != 0;
  171. }
  172.  
  173. inline int operator <  (const Rational& x, const Rational& y)
  174. {
  175.   return compare(x, y) <  0; 
  176. }
  177.  
  178. inline int operator <= (const Rational& x, const Rational& y)
  179. {
  180.   return compare(x, y) <= 0; 
  181. }
  182.  
  183. inline int operator >  (const Rational& x, const Rational& y)
  184. {
  185.   return compare(x, y) >  0; 
  186. }
  187.  
  188. inline int operator >= (const Rational& x, const Rational& y)
  189. {
  190.   return compare(x, y) >= 0; 
  191. }
  192.  
  193. inline int sign(const Rational& x)
  194. {
  195.   return sign(x.num);
  196. }
  197.  
  198. inline void Rational::negate()
  199. {
  200.   num.negate();
  201. }
  202.  
  203.  
  204. inline void Rational::operator += (const Rational& y) 
  205. {
  206.   add(*this, y, *this);
  207. }
  208.  
  209. inline void Rational::operator -= (const Rational& y) 
  210. {
  211.   sub(*this, y, *this);
  212. }
  213.  
  214. inline void Rational::operator *= (const Rational& y) 
  215. {
  216.   mul(*this, y, *this);
  217. }
  218.  
  219. inline void Rational::operator /= (const Rational& y) 
  220. {
  221.   div(*this, y, *this);
  222. }
  223.  
  224. inline const Integer& Rational::numerator() const { return num; }
  225. inline const Integer& Rational::denominator() const { return den; }
  226. inline Rational::operator double() const { return ratio(num, den); }
  227.  
  228. #ifdef __GNUG__
  229. inline Rational operator <? (const Rational& x, const Rational& y)
  230. {
  231.   if (compare(x, y) <= 0) return x; else return y;
  232. }
  233.  
  234. inline Rational operator >? (const Rational& x, const Rational& y)
  235. {
  236.   if (compare(x, y) >= 0) return x; else return y;
  237. }
  238. #endif
  239.  
  240. #if defined(__GNUG__) && !defined(NO_NRV)
  241.  
  242. inline Rational operator + (const Rational& x, const Rational& y) return r
  243. {
  244.   add(x, y, r);
  245. }
  246.  
  247. inline Rational operator - (const Rational& x, const Rational& y) return r
  248. {
  249.   sub(x, y, r);
  250. }
  251.  
  252. inline Rational operator * (const Rational& x, const Rational& y) return r
  253. {
  254.   mul(x, y, r);
  255. }
  256.  
  257. inline Rational operator / (const Rational& x, const Rational& y) return r
  258. {
  259.   div(x, y, r);
  260. }
  261.  
  262. #else /* NO_NRV */
  263.  
  264. inline Rational operator + (const Rational& x, const Rational& y) 
  265. {
  266.   Rational r; add(x, y, r); return r;
  267. }
  268.  
  269. inline Rational operator - (const Rational& x, const Rational& y)
  270. {
  271.   Rational r; sub(x, y, r); return r;
  272. }
  273.  
  274. inline Rational operator * (const Rational& x, const Rational& y)
  275. {
  276.   Rational r; mul(x, y, r); return r;
  277. }
  278.  
  279. inline Rational operator / (const Rational& x, const Rational& y)
  280. {
  281.   Rational r; div(x, y, r); return r;
  282. }
  283. #endif
  284.  
  285. #endif
  286.