fraction.h

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 
00032 #ifndef __FRACTION_H
00033 #define __FRACTION_H
00034 
00035 #include "common/h/Types.h"
00036 #include "common/h/std_namesp.h"
00037 
00038 #if defined(os_windows)
00039                         // exception SPECIFICATIONS aren't
00040 #pragma warning( disable : 4290 )       // implemented yet on NT
00041 #endif
00042 
00043 
00044 class COMMON_EXPORT fraction {
00045   mutable int64_t numer;
00046   mutable int64_t denom;
00047   // largest multiplicand until an interim overflow will occur, and need to 
00048   // handle by different means
00049   mutable int64_t interimMultOverflowPt;  
00050   // largest multipland until a final overflow will occur, no way to handle
00051   // because result value is just to large to handle with an int64_t
00052   mutable int64_t   finalMultOverflowPt;
00053  public:
00054   typedef enum { sparse, verbose } ostream_fmt; 
00055   static ostream_fmt curFmt;
00056 
00057   fraction() : numer(0), denom(0), 
00058     interimMultOverflowPt(0), finalMultOverflowPt(0)  { }
00059   explicit fraction(int64_t n) : numer(n), denom(I64_C(1))  { 
00060     calcOverflowPts();
00061   }
00062   explicit fraction(int64_t n, int64_t d) : numer(n), denom(d)  { 
00063     calcOverflowPts();
00064   }
00065   // default copy constructor
00066 
00067   // Selectors
00068   int64_t getNumer() const {  return numer; }
00069   int64_t getDenom() const {  return denom; }
00070   // returns an integer representation of the fraction
00071   int64_t getI() const {
00072     return numer / denom;
00073   }
00074   // returns a double representation of the fraction
00075   double  getD() const { return (double) numer / (double) denom; }
00076   int64_t getInterimMultOverflowPt() const {  
00077     return interimMultOverflowPt; 
00078   }
00079   int64_t   getFinalMultOverflowPt() const {  
00080     return   finalMultOverflowPt; 
00081   }
00082 
00083 /* A fast specialized multiplication of a fraction and an int64
00084    uses a special method that can keep from an interim overflow from occurring
00085    precise in regards to the result (doesn't round, ie. rounds result down).
00086    Returns int int64_t instead of a fraction, like the operator* does.
00087    If a final overflow occurs, prints an error message and returns the
00088    largest integer.
00089 */
00090   int64_t multReturnInt64(int64_t b) const;
00091 
00092   fraction reciprocal() const {  
00093     return fraction(denom, numer); 
00094   }
00095  private:
00096   int64_t multNoInterimOverflow(int64_t b) const {
00097     int64_t intdiv = b / getDenom();
00098     int64_t decrem = b % getDenom();
00099     return intdiv*getNumer() + decrem*getNumer()/getDenom();
00100   }
00101 
00102  public:
00103   // Mutators
00104   void setNumer(int64_t n) {
00105     numer = n;
00106     calcOverflowPts();
00107   }
00108   void setDenom(int64_t d) { 
00109     denom = d; 
00110     calcOverflowPts();
00111   }
00112  private:
00113   void setRaw(int64_t n, int64_t d) {
00114     numer = n;
00115     denom = d;
00116   }
00117  public:
00118   void set(int64_t n, int64_t d) { 
00119     setRaw(n,d);
00120     calcOverflowPts();
00121   }
00122   // This is const, because only modifying internal variables
00123   void calcOverflowPts() const;
00124 
00125   // A fraction is still logically unchanged when you reduce it, so consider
00126   // it a constant operation  eg. this will work:
00127   //   const fraction a(2,4);  a.reduce();
00128   void reduce() const;
00129 };
00130 
00131 
00132 ostream& operator<<(ostream&s, const fraction::ostream_fmt u);
00133 ostream& operator<<(ostream&s, const fraction &z);
00134 
00135 /* If you want these, feel free to write them
00136 const fraction &operator+(const fraction &a, const fraction &b); {
00137 const fraction &operator-(const fraction &a, const fraction &b);
00138 */
00139 
00140 COMMON_EXPORT int64_t gcd(int64_t a, int64_t b);
00141 COMMON_EXPORT int64_t lcd(int64_t a, int64_t b);
00142 
00143 inline void fraction::reduce() const {
00144   int64_t igcd = gcd(numer, denom);
00145   numer = numer / igcd;
00146   denom = denom / igcd;
00147   calcOverflowPts();
00148 }
00149 
00150 // fraction * double
00151 inline double operator*(const fraction &a, const double d) {
00152   return d * a.getD();
00153 }
00154 // double   * fraction
00155 inline double operator*(const double d, const fraction &a) {
00156   return a * d;
00157 }
00158 
00159 // Upon an interim or final overflow, prints an error message and returns
00160 // the largest fraction representable.
00161 // fraction * int64_t
00162 const fraction operator*(const fraction &a, int64_t b);
00163 // int64_t  * fraction
00164 inline const fraction operator*(int64_t a, const fraction &b) {
00165   return b * a;
00166 }
00167 
00168 // fraction + fraction
00169 //const fraction operator+(const fraction &a, const fraction &b);
00170 // fraction - fraction
00171 //const fraction operator-(const fraction &a, const fraction &b);
00172 
00173 // fraction * fraction
00174 /* Feel free to implement if needed:
00175 const fraction operator*(const fraction &a, const fraction &b); 
00176 */
00177 
00178 
00179 inline const fraction operator/(const fraction &a, const fraction &b) {
00180   return fraction(a.getNumer() * b.getDenom(), a.getDenom() * b.getNumer());
00181 }
00182 
00183 inline bool operator==(const fraction &a, const fraction &b) {
00184   fraction ar = a;
00185   ar.reduce();
00186   fraction br = b;
00187   br.reduce();
00188   return ((ar.getNumer() == br.getNumer()) && (ar.getDenom() == br.getDenom()));
00189 }
00190 inline bool operator!=(const fraction &a, const fraction &b) {
00191   fraction ar = a;
00192   ar.reduce();
00193   fraction br = b;
00194   br.reduce();
00195   return ((ar.getNumer() != br.getNumer()) || (ar.getDenom() != br.getDenom()));
00196 }
00197 
00198 // getFrSpec is a helper routine for the gt, lt operators
00199 // n : numerator,   d: denominator
00200 // ra: returns the numerator high 32 bits / denom (always positive)
00201 // rb: returns the numerator low  32 bits / denom (always positive)
00202 // rsign: -1 for negative, 1 for positive result
00203 void getFrSpec(int64_t n, int64_t d, double *ra, double *rb, int *rsign);
00204 bool operator>(const fraction &a, const fraction &b);
00205 bool operator<(const fraction &a, const fraction &b);
00206 bool operator>=(const fraction &a, const fraction &b);
00207 bool operator<=(const fraction &a, const fraction &b);
00208 
00209 
00210 
00211 
00212 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1