numeric-lib/bigfraction.h
00001 /*
00002  * bigfraction.h
00003  *
00004  *  Created on: Dec 8, 2008
00005  *      Author: tdillig
00006  *
00007  *  Bigfraction library based on bignum.h.
00008  */
00009 
00010 #ifndef BIGFRACTION_H_
00011 #define BIGFRACTION_H_
00012 
00013 #include "bignum.h"
00014 
00015 class bigfraction {
00016 private:
00017         bignum n;
00018         bignum d;
00019 public:
00020         inline bigfraction():n(0), d(1)
00021         {
00022 
00023         }
00024         inline bigfraction(bignum n):n(n), d(1)
00025         {
00026 
00027         }
00028         inline bigfraction(long int n):n(n), d(1)
00029         {
00030 
00031         }
00032         inline bigfraction(bignum n, bignum d):n(n), d(d)
00033         {
00034                 simplify();
00035         }
00036         inline const bigfraction& operator=(bigfraction other)
00037         {
00038                 n =other.n;
00039                 d =other.d;
00040                 simplify();
00041                 return *this;
00042 
00043         }
00044         inline const bigfraction& operator=(bignum other)
00045         {
00046                 n =other;
00047                 d =1;
00048                 return *this;
00049 
00050         }
00051 
00052         inline bool is_integer()
00053         {
00054                 return (d==1 || n==0);
00055         }
00056 
00057         inline double to_double()
00058         {
00059                 return n.to_double()/d.to_double();
00060         }
00061 
00062         inline ~bigfraction()
00063         {
00064 
00065         }
00066         inline string to_string()
00067         {
00068                 string res;
00069                 if(d == 0) return "NaN";
00070                 if(d == 1) return n.to_string();
00071                 if(n == 0) return "0";
00072                 return n.to_string() + "/" + d.to_string();
00073 
00074         }
00075         friend ostream& operator <<(ostream &os,const bigfraction &obj);
00076 
00077         /*
00078          * Arithmetic operator
00079          */
00080 
00081         inline void operator*=(bigfraction& other){
00082                 n *=other.n;
00083                 d *=other.d;
00084                 simplify();
00085         }
00086 
00087         inline void operator*=(bignum other){
00088                 n *=other;
00089                 simplify();
00090         }
00091 
00092 
00093         inline void operator/=(bigfraction& other){
00094                 n *=other.d;
00095                 d *=other.n;
00096                 simplify();
00097         }
00098 
00099         inline void operator/=(bignum other){
00100                 d *=other;
00101                 simplify();
00102         }
00103 
00104 
00105         inline void operator+=(bigfraction other){
00106                 bignum n1 = n*other.d;
00107                 bignum n2 = other.n * d;
00108                 d = d*other.d;
00109                 n = n1+n2;
00110                 simplify();
00111 
00112         }
00113 
00114         inline void operator+=(bignum other){
00115                 bignum other_n = other * d;
00116                 n += other_n;
00117                 simplify();
00118         }
00119 
00120         inline void operator-=(bigfraction other){
00121                 bignum n1 = n*other.d;
00122                 bignum n2 = other.n * d;
00123                 d = d*other.d;
00124                 n = n1-n2;
00125                 simplify();
00126 
00127         }
00128 
00129         inline void operator-=(bignum other){
00130                 bignum other_n = other * d;
00131                 n -= other_n;
00132                 simplify();
00133         }
00134 
00135 
00136         inline bigfraction operator*(bigfraction& other)
00137         {
00138                 bigfraction b(n*other.n, d*other.d);
00139                 return b;
00140         }
00141 
00142         inline bigfraction operator*(bignum other)
00143         {
00144                 bigfraction b(n*other, d);
00145                 return b;
00146         }
00147 
00148 
00149 
00150         inline bigfraction operator/(bigfraction& other)
00151         {
00152                 bigfraction b(n*other.d, d*other.n);
00153                 return b;
00154         }
00155 
00156         inline bigfraction operator/(bignum other)
00157         {
00158                 bigfraction b(n, d*other);
00159                 return b;
00160         }
00161 
00162 
00163 
00164         inline bigfraction operator+(bigfraction& other)
00165         {
00166                 bignum n1 = n*other.d;
00167                 bignum n2 =other.n*d;
00168                 bignum new_n = n1+n2;
00169                 bignum new_d =  d*other.d;
00170                 bigfraction b(new_n, new_d);
00171                 return b;
00172         }
00173 
00174         inline bigfraction operator+(bignum other)
00175         {
00176                 bignum n1 = other*d;
00177                 bignum new_n = n+n1;
00178                 bigfraction b(new_n, d);
00179                 return b;
00180         }
00181 
00182         inline bigfraction operator-(bigfraction& other)
00183         {
00184                 bigfraction b((n*other.d)-(other.n*d), d*other.d);
00185                 return b;
00186         }
00187 
00188         inline bigfraction operator-(bignum other)
00189         {
00190                 bigfraction b(n-other*d, d);
00191                 return b;
00192         }
00193 
00194         inline bigfraction operator-()
00195         {
00196                 bigfraction b(-n, d);
00197                 return b;
00198         }
00199 
00200         /*
00201          * Logical operators
00202          */
00203         inline bool operator==(bigfraction other)
00204         {
00205                 return n==other.n && d==other.d;
00206         }
00207 
00208         inline bool operator!=(bigfraction other)
00209         {
00210                 return n!=other.n || d!=other.d;
00211         }
00212 
00213         inline bool operator!=(bignum other)
00214         {
00215                 return d!=1 || n!=other;
00216         }
00217 
00218         inline bool operator<(bigfraction other)
00219         {
00220                 bignum n1 = n*other.d;
00221                 bignum n2 = other.n*d;
00222                 return n1<n2;
00223         }
00224         inline bool operator<(bignum other)
00225         {
00226                 bignum n2 = other*d;
00227                 return n<n2;
00228         }
00229 
00230         inline bool operator<=(bigfraction other)
00231         {
00232                 bignum n1 = n*other.d;
00233                 bignum n2 = other.n*d;
00234                 return n1<=n2;
00235         }
00236         inline bool operator<=(bignum other)
00237         {
00238                 bignum n2 = other*d;
00239                 return n<=n2;
00240         }
00241         inline bool operator>(bigfraction other)
00242         {
00243                 bignum n1 = n*other.d;
00244                 bignum n2 = other.n*d;
00245                 return n1>n2;
00246         }
00247         inline bool operator>(bignum other)
00248         {
00249                 bignum n2 = other*d;
00250                 return n>n2;
00251         }
00252         inline bool operator>=(bigfraction other)
00253         {
00254                 bignum n1 = n*other.d;
00255                 bignum n2 = other.n*d;
00256                 return n1>=n2;
00257         }
00258         inline bool operator>=(bignum other)
00259         {
00260                 bignum n2 = other*d;
00261                 return n>=n2;
00262         }
00263 
00264         inline bignum round_down()
00265         {
00266                 assert(d>=0);
00267                 if(n<0) {
00268                         return (n/d)-1;
00269                 }
00270                 else return n/d;
00271         }
00272 
00273         inline bignum round_up()
00274         {
00275                 assert(d>=0);
00276                 if(d==1) return n;
00277                 if(n<0) {
00278                         return n/d;
00279                 }
00280                 else return (n/d+1);
00281         }
00282 
00283 
00284         inline bignum get_numerator()
00285         {
00286                 return n;
00287         }
00288         inline bignum get_denominator()
00289         {
00290                 return d;
00291         }
00292 
00293 private:
00294         void simplify()
00295         {
00296 
00297                 if(d<0) {
00298                         d=-d;
00299                         n=-n;
00300                 }
00301                 bignum gcd = n.compute_gcd(d);
00302                 if(gcd == 1 || gcd == 0) return;
00303                 n/=gcd;
00304                 d/=gcd;
00305 
00306         }
00307 };
00308 
00309 #endif /* BIGFRACTION_H_ */