home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / libg++-2.6-fsf.lha / libg++-2.6 / libg++ / src / Rational.h < prev    next >
C/C++ Source or Header  |  1994-05-11  |  8KB  |  289 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. #endif
  24. #define _Rational_h 1
  25.  
  26. #include <Integer.h>
  27. #include <math.h>
  28.  
  29. class Rational
  30. {
  31. protected:
  32.   Integer          num;
  33.   Integer          den;
  34.  
  35.   void             normalize();
  36.  
  37. public:
  38.                    Rational();
  39.                    Rational(double);
  40.                    Rational(int n);
  41.                    Rational(long n);
  42.                    Rational(int n, int d);
  43.                    Rational(long n, long d);
  44.                    Rational(long n, unsigned long d);
  45.                    Rational(unsigned long n, long d);
  46.                    Rational(unsigned long n, unsigned long d);
  47.                    Rational(const Integer& n);
  48.                    Rational(const Integer& n, const Integer& d);
  49.                    Rational(const Rational&);
  50.  
  51.                   ~Rational();
  52.  
  53.   Rational&        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.   Rational&        operator += (const Rational& y);
  68.   Rational&        operator -= (const Rational& y);
  69.   Rational&        operator *= (const Rational& y);
  70.   Rational&        operator /= (const Rational& y);
  71.  
  72. #if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
  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, const 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.   int           fits_in_float() const;
  106.   int           fits_in_double() const;
  107.  
  108. // procedural versions of operators
  109.  
  110.   friend int       compare(const Rational& x, const Rational& y);
  111.   friend void      add(const Rational& x, const Rational& y, Rational& dest);
  112.   friend void      sub(const Rational& x, const Rational& y, Rational& dest);
  113.   friend void      mul(const Rational& x, const Rational& y, Rational& dest);
  114.   friend void      div(const Rational& x, const Rational& y, Rational& dest);
  115.  
  116. // error detection
  117.  
  118.   void    error(const char* msg) const;
  119.   int              OK() const;
  120.  
  121. };
  122.  
  123. typedef Rational RatTmp; // backwards compatibility
  124.  
  125. inline Rational::Rational() : num(&_ZeroRep), den(&_OneRep) {}
  126. inline Rational::~Rational() {}
  127.  
  128. inline Rational::Rational(const Rational& y) :num(y.num), den(y.den) {}
  129.  
  130. inline Rational::Rational(const Integer& n) :num(n), den(&_OneRep) {}
  131.  
  132. inline Rational::Rational(const Integer& n, const Integer& d) :num(n),den(d)
  133. {
  134.   normalize();
  135. }
  136.  
  137. inline Rational::Rational(long n) :num(n), den(&_OneRep) { }
  138.  
  139. inline Rational::Rational(int n) :num(n), den(&_OneRep) { }
  140.  
  141. inline Rational::Rational(long n, long d) :num(n), den(d) { normalize(); }
  142. inline Rational::Rational(int n, int d) :num(n), den(d) { normalize(); }
  143. inline Rational::Rational(long n, unsigned long d) :num(n), den(d)
  144. {
  145.   normalize();
  146. }
  147. inline Rational::Rational(unsigned long n, long d) :num(n), den(d)
  148. {
  149.   normalize();
  150. }
  151. inline Rational::Rational(unsigned long n, unsigned long d) :num(n), den(d)
  152. {
  153.   normalize();
  154. }
  155.  
  156. inline Rational& Rational::operator =  (const Rational& y)
  157. {
  158.   num = y.num;  den = y.den;
  159.   return *this;
  160. }
  161.  
  162. inline int operator == (const Rational& x, const Rational& y)
  163. {
  164.   return compare(x.num, y.num) == 0 && compare(x.den, y.den) == 0;
  165. }
  166.  
  167. inline int operator != (const Rational& x, const Rational& y)
  168. {
  169.   return compare(x.num, y.num) != 0 || compare(x.den, y.den) != 0;
  170. }
  171.  
  172. inline int operator <  (const Rational& x, const Rational& y)
  173. {
  174.   return compare(x, y) <  0; 
  175. }
  176.  
  177. inline int operator <= (const Rational& x, const Rational& y)
  178. {
  179.   return compare(x, y) <= 0; 
  180. }
  181.  
  182. inline int operator >  (const Rational& x, const Rational& y)
  183. {
  184.   return compare(x, y) >  0; 
  185. }
  186.  
  187. inline int operator >= (const Rational& x, const Rational& y)
  188. {
  189.   return compare(x, y) >= 0; 
  190. }
  191.  
  192. inline int sign(const Rational& x)
  193. {
  194.   return sign(x.num);
  195. }
  196.  
  197. inline void Rational::negate()
  198. {
  199.   num.negate();
  200. }
  201.  
  202.  
  203. inline Rational& Rational::operator += (const Rational& y) 
  204. {
  205.   add(*this, y, *this);
  206.   return *this;
  207. }
  208.  
  209. inline Rational& Rational::operator -= (const Rational& y) 
  210. {
  211.   sub(*this, y, *this);
  212.   return *this;
  213. }
  214.  
  215. inline Rational& Rational::operator *= (const Rational& y) 
  216. {
  217.   mul(*this, y, *this);
  218.   return *this;
  219. }
  220.  
  221. inline Rational& Rational::operator /= (const Rational& y) 
  222. {
  223.   div(*this, y, *this);
  224.   return *this;
  225. }
  226.  
  227. inline const Integer& Rational::numerator() const { return num; }
  228. inline const Integer& Rational::denominator() const { return den; }
  229. inline Rational::operator double() const { return ratio(num, den); }
  230.  
  231. #if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
  232. inline Rational operator <? (const Rational& x, const Rational& y)
  233. {
  234.   if (compare(x, y) <= 0) return x; else return y;
  235. }
  236.  
  237. inline Rational operator >? (const Rational& x, const Rational& y)
  238. {
  239.   if (compare(x, y) >= 0) return x; else return y;
  240. }
  241. #endif
  242.  
  243. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  244.  
  245. inline Rational operator + (const Rational& x, const Rational& y) return r
  246. {
  247.   add(x, y, r);
  248. }
  249.  
  250. inline Rational operator - (const Rational& x, const Rational& y) return r
  251. {
  252.   sub(x, y, r);
  253. }
  254.  
  255. inline Rational operator * (const Rational& x, const Rational& y) return r
  256. {
  257.   mul(x, y, r);
  258. }
  259.  
  260. inline Rational operator / (const Rational& x, const Rational& y) return r
  261. {
  262.   div(x, y, r);
  263. }
  264.  
  265. #else /* NO_NRV */
  266.  
  267. inline Rational operator + (const Rational& x, const Rational& y) 
  268. {
  269.   Rational r; add(x, y, r); return r;
  270. }
  271.  
  272. inline Rational operator - (const Rational& x, const Rational& y)
  273. {
  274.   Rational r; sub(x, y, r); return r;
  275. }
  276.  
  277. inline Rational operator * (const Rational& x, const Rational& y)
  278. {
  279.   Rational r; mul(x, y, r); return r;
  280. }
  281.  
  282. inline Rational operator / (const Rational& x, const Rational& y)
  283. {
  284.   Rational r; div(x, y, r); return r;
  285. }
  286. #endif
  287.  
  288. #endif
  289.