fraction.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
00048
00049 mutable int64_t interimMultOverflowPt;
00050
00051
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
00066
00067
00068 int64_t getNumer() const { return numer; }
00069 int64_t getDenom() const { return denom; }
00070
00071 int64_t getI() const {
00072 return numer / denom;
00073 }
00074
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
00084
00085
00086
00087
00088
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
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
00123 void calcOverflowPts() const;
00124
00125
00126
00127
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
00136
00137
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
00151 inline double operator*(const fraction &a, const double d) {
00152 return d * a.getD();
00153 }
00154
00155 inline double operator*(const double d, const fraction &a) {
00156 return a * d;
00157 }
00158
00159
00160
00161
00162 const fraction operator*(const fraction &a, int64_t b);
00163
00164 inline const fraction operator*(int64_t a, const fraction &b) {
00165 return b * a;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
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
00199
00200
00201
00202
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