rational.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file rational.h
00004  * 
00005  * Author: Sergey Berezin
00006  * 
00007  * Created: Dec 12 22:00:18 GMT 2002
00008  *
00009  * <hr>
00010  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00011  * Junior University and by New York University. 
00012  *
00013  * License to use, copy, modify, sell and/or distribute this software
00014  * and its documentation for any purpose is hereby granted without
00015  * royalty, subject to the terms and conditions defined in the \ref
00016  * LICENSE file provided with this distribution.  In particular:
00017  *
00018  * - The above copyright notice and this permission notice must appear
00019  * in all copies of the software and related documentation.
00020  *
00021  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00022  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00023  * 
00024  * <hr>
00025  * 
00026  */
00027 /*****************************************************************************/
00028 // Class: Rational
00029 // Author: Sergey Berezin, 12/12/2002 (adapted from Bignum)
00030 //
00031 // Description: This is an abstration of a rational with arbitrary
00032 // precision.  It provides a constructor from a pair of ints and
00033 // strings, overloaded operator{+,-,*,/}, assignment, etc.  The
00034 // current implementation uses GMP mpq_class.
00035 ///////////////////////////////////////////////////////////////////////////////
00036 
00037 #ifndef _CVC_lite__rational_h_
00038 #define _CVC_lite__rational_h_
00039 
00040 // Do not include <gmpxx.h> here; it contains some depricated C++
00041 // headers.  We only include it in the .cpp file.
00042 
00043 #include <vector>
00044 #include "debug.h"
00045 
00046 // To be defined only in bignum.cpp
00047 namespace CVCL {
00048 
00049   class Rational {
00050   private:
00051     class Impl;
00052     Impl *d_n;
00053     // Debugging
00054 #ifdef _DEBUG_RATIONAL_
00055     // Encapsulate static values in a function to guarantee
00056     // initialization when we need it
00057     int& getCreated() {
00058       static int num_created = 0;
00059       return(num_created);
00060     }
00061       
00062     int& getDeleted() {
00063       static int num_deleted = 0;
00064       return(num_deleted);
00065     }
00066       
00067     void printStats();
00068 #endif
00069     // Private constructor (for internal consumption only)
00070     Rational(const Impl& t);
00071 
00072   public:
00073     // Constructors
00074     Rational();
00075     // Copy constructor
00076     Rational(const Rational &n);
00077     Rational(int n, int d = 1);
00078     Rational(const char* n, int base = 10);
00079     Rational(const std::string& n, int base = 10);
00080     Rational(const char* n, const char* d, int base = 10);
00081     Rational(const std::string& n, const std::string& d, int base = 10);
00082     // Destructor
00083     ~Rational();
00084 
00085     // Assignment
00086     Rational& operator=(const Rational& n);
00087 
00088     std::string toString(int base = 10) const;
00089 
00090     // Compute hash value (for DAG expression representation)
00091     size_t hash() const;
00092 
00093     friend bool operator==(const Rational &n1, const Rational &n2);
00094     friend bool operator<(const Rational &n1, const Rational &n2);
00095     friend bool operator<=(const Rational &n1, const Rational &n2);
00096     friend bool operator>(const Rational &n1, const Rational &n2);
00097     friend bool operator>=(const Rational &n1, const Rational &n2);
00098     friend bool operator!=(const Rational &n1, const Rational &n2);
00099     friend Rational operator+(const Rational &n1, const Rational &n2);
00100     friend Rational operator-(const Rational &n1, const Rational &n2);
00101     friend Rational operator*(const Rational &n1, const Rational &n2);
00102     friend Rational operator/(const Rational &n1, const Rational &n2);
00103     // 'mod' operator, defined only for integer values of n1 and n2
00104     friend Rational operator%(const Rational &n1, const Rational &n2);
00105 
00106     // Unary minus
00107     Rational operator-() const;
00108     Rational &operator+=(const Rational &n2);
00109     Rational &operator-=(const Rational &n2);
00110     Rational &operator*=(const Rational &n2);
00111     Rational &operator/=(const Rational &n2);
00112     //! Prefix increment
00113     const Rational& operator++() { *this = (*this)+1; return *this; }
00114     //! Postfix increment
00115     Rational operator++(int) { Rational x(*this); *this = x+1; return x; }
00116     //! Prefix decrement
00117     const Rational& operator--() { *this = (*this)-1; return *this; }
00118     //! Postfix decrement
00119     Rational operator--(int) { Rational x(*this); *this = x-1; return x; }
00120 
00121     // Resust is integer
00122     Rational getNumerator() const;
00123     Rational getDenominator() const;
00124 
00125     // Equivalent to (getDenominator() == 1), but possibly more efficient
00126     bool isInteger() const;
00127     // Convert to int; defined only on integer values
00128     int getInt() const;
00129     // Equivalent to (*this >= 0 && isInteger())
00130     bool isUnsigned() const { return (isInteger() && (*this) >= 0); }
00131     // Convert to unsigned int; defined only on non-negative integer values
00132     unsigned int getUnsigned() const;
00133 
00134     friend std::ostream &operator<<(std::ostream &os, const Rational &n);
00135 
00136     /* Computes gcd and lcm on *integer* values. Result is always a
00137        positive integer. */
00138 
00139     friend Rational gcd(const Rational &x, const Rational &y);
00140     friend Rational gcd(const std::vector<Rational> &v);
00141     friend Rational lcm(const Rational &x, const Rational &y);
00142     friend Rational lcm(const std::vector<Rational> &v);
00143 
00144     friend Rational abs(const Rational &x);
00145 
00146     //! Compute the floor of x (result is an integer)
00147     friend Rational floor(const Rational &x);
00148     //! Compute the ceiling of x (result is an integer)
00149     friend Rational ceil(const Rational &x);
00150     //! Compute non-negative remainder for *integer* x,y.
00151     friend Rational mod(const Rational &x, const Rational &y);
00152 
00153     // For debugging, to be able to print in gdb
00154     void print() const;
00155 
00156   }; // Rational class
00157 
00158   //! Raise 'base' into the power of 'pow' (pow must be an integer)
00159   inline Rational pow(Rational pow, const Rational& base) {
00160     DebugAssert(pow.isInteger(), "pow("+pow.toString()
00161                 +", "+base.toString()+")");
00162     bool neg(pow < 0);
00163     if(neg) pow = -pow;
00164     Rational res(1);
00165     for(; pow > 0; --pow) res *= base;
00166     if(neg) res = 1/res;
00167     return res;
00168   }
00169 
00170   
00171   // Methods creating new Rational values, similar to the
00172   // constructors, but can be nested
00173   inline Rational newRational(int n, int d = 1) { return Rational(n, d); }
00174   inline Rational newRational(const char* n, int base = 10)
00175     { return Rational(n, base); }
00176   inline Rational newRational(const std::string& n, int base = 10)
00177     { return Rational(n, base); }
00178   inline Rational newRational(const char* n, const char* d, int base = 10)
00179     { return Rational(n, d, base); }
00180   inline Rational newRational(const std::string& n, const std::string& d,
00181                               int base = 10)
00182     { return Rational(n, d, base); }
00183     
00184   // Debugging print
00185   void printRational(const Rational &x);
00186 
00187 }; // end of namespace CVCL
00188 
00189 #endif

Generated on Thu Apr 13 16:57:32 2006 for CVC Lite by  doxygen 1.4.4