fraction.C
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 #include "common/h/fraction.h"
00032 #include "common/h/int64iostream.h"
00033
00034 fraction::ostream_fmt fraction::curFmt = sparse;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 int64_t lcd(int64_t a, int64_t b) {
00049 int64_t _gcd = gcd(a,b);
00050 if(a > b) { a = a / _gcd; }
00051 else { b = b / _gcd; }
00052 int64_t overflowPt = I64_MAX / b;
00053 if(a > overflowPt) { cerr << "lcd: overflow\n"; return -1; }
00054 return a * b;
00055 }
00056
00057 int64_t gcd(int64_t a, int64_t b) {
00058 if (b == 0) return a;
00059 return gcd(b, a % b);
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 const fraction operator*(const fraction &a, int64_t b) {
00084 if(b < a.getInterimMultOverflowPt()) {
00085
00086 return fraction(b * a.getNumer(), a.getDenom());
00087 } else if(b <= a.getFinalMultOverflowPt()) {
00088
00089 cerr << "fraction::operator*- an interim overflow has occurred\n";
00090 return fraction(I64_MAX);
00091 } else {
00092 cerr << "fraction::operator*- a final overflow has occurred\n";
00093 return fraction(I64_MAX);
00094 }
00095 }
00096
00097 int64_t fraction::multReturnInt64(int64_t b) const {
00098 int64_t ret = 0;
00099 if(b < getInterimMultOverflowPt()) {
00100
00101 fraction fres(b * getNumer(), getDenom());
00102 ret = fres.getI();
00103 } else if(b <= getFinalMultOverflowPt()) {
00104
00105 ret = multNoInterimOverflow(b);
00106 } else {
00107 cerr << "fraction::multReturnInt64- a final overflow has occurred\n";
00108 return I64_MAX;
00109 }
00110 return ret;
00111 }
00112
00113 void fraction::calcOverflowPts() const {
00114 if(getNumer() == 0)
00115 interimMultOverflowPt = I64_MAX;
00116 else
00117 interimMultOverflowPt = I64_MAX / getNumer();
00118 fraction recip;
00119 recip.setRaw(getDenom(), getNumer());
00120 if(recip.getDenom()==0 || recip.getD() > 1.0)
00121 finalMultOverflowPt = I64_MAX;
00122 else
00123 finalMultOverflowPt = recip.multNoInterimOverflow(I64_MAX);
00124 }
00125
00126
00127
00128
00129
00130
00131 void getFrSpec(int64_t n, int64_t d, double *ra, double *rb, int *rsign) {
00132 int sign = 1;
00133 if(n < 0) { n = -n; sign = -sign; }
00134 if(d < 0) { d = -d; sign = -sign; }
00135 *rsign = sign;
00136 int64_t upperI = n & I64_C(0xFFFFFFFF00000000);
00137 *ra = static_cast<double>(upperI) / static_cast<double>(d);
00138 int64_t lowerI = n & 0xFFFFFFFF;
00139 *rb = static_cast<double>(lowerI) / static_cast<double>(d);
00140 }
00141
00142
00143
00144 bool operator>(const fraction &a, const fraction &b) {
00145 double ax, ay;
00146 int as;
00147 getFrSpec(a.getNumer(), a.getDenom(), &ax, &ay, &as);
00148 if(as == -1) { ax =- ax; ay =-ay; }
00149
00150 double bx, by;
00151 int bs;
00152 getFrSpec(b.getNumer(), b.getDenom(), &bx, &by, &bs);
00153 if(bs == -1) { bx =- bx; by =-by; }
00154 return (ax > bx || (ax == bx && ay > by));
00155 }
00156
00157 bool operator<(const fraction &a, const fraction &b) {
00158 double ax, ay;
00159 int as;
00160 getFrSpec(a.getNumer(), a.getDenom(), &ax, &ay, &as);
00161 if(as == -1) { ax =- ax; ay =-ay; }
00162
00163 double bx, by;
00164 int bs;
00165 getFrSpec(b.getNumer(), b.getDenom(), &bx, &by, &bs);
00166 if(bs == -1) { bx =- bx; by =-by; }
00167 return (ax < bx || (ax == bx && ay < by));
00168 }
00169
00170 bool operator>=(const fraction &a, const fraction &b) {
00171 return ((a > b) || (a == b));
00172 }
00173
00174 bool operator<=(const fraction &a, const fraction &b) {
00175 return ((a < b) || (a == b));
00176 }
00177
00178 ostream& operator<<(ostream&s, const fraction::ostream_fmt u) {
00179 fraction::curFmt = u;
00180 return s;
00181 }
00182
00183 ostream& operator<<(ostream&s, const fraction &z) {
00184 if(fraction::curFmt == fraction::sparse) {
00185 s << "(" << z.getNumer() << "/" << z.getDenom() << ")";
00186 } else {
00187 s << "(" << z.getNumer() << "/" << z.getDenom() << " - interimOvflw:";
00188 s << z.getInterimMultOverflowPt() << ", finalOvflw: "
00189 << z.getFinalMultOverflowPt();
00190 }
00191 return s;
00192 }
00193
00194