00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "rational.h"
00013 #include <cstdlib>
00014 #include <cctype>
00015
00016 OPEN_namespace(ADH)
00017 USING_namespace(ADH);
00018
00019 #ifndef NDEBUG
00020 #include "check_ok.cpp"
00021 #endif // NDEBUG
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 long mcd(long x, long y) {
00040 long g = (x < 0 ? -x : x);
00041 long r = (y < 0 ? -y : y);
00042 long temp;
00043
00044 do {
00045 temp = r;
00046 r = g % r;
00047 g = temp;
00048 } while (0 != r);
00049
00050 return g;
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void rational::Simplify() {
00065 if (m_num == 0) {
00066 m_den = 1;
00067 }
00068 long divisor = mcd(m_num, m_den);
00069 if (divisor > 1) {
00070 m_num /= divisor;
00071 m_den /= divisor;
00072 }
00073 if (m_den < 0) {
00074 m_num = -m_num;
00075 m_den = -m_den;
00076 }
00077 }
00078
00079
00080 rational& rational::operator += (const rational& otro) {
00081 m_num = m_num * otro.m_den + m_den * otro.m_num;
00082 m_den *= otro.m_den;
00083 Simplify();
00084
00085 return *this;
00086 }
00087
00088
00089
00090 rational& rational::operator -= (const rational& num) {
00091 long oldm_den = m_den;
00092 long oldm_num = m_num;
00093 long d = num.m_den;
00094 long n = num.m_num;
00095
00096 m_den *= d;
00097 m_num = oldm_num * d - oldm_den * n;
00098 Simplify();
00099
00100 return *this;
00101 }
00102
00103
00104
00105 rational& rational::fromString (const char* nStr) {
00106 char ch;
00107
00108 bool es_positivo = true;
00109
00110
00111 do {
00112 ch = *nStr; nStr++;
00113 if (ch == '-') {
00114 es_positivo = !es_positivo;
00115 }
00116 } while (!isdigit(ch));
00117
00118
00119 long num = 0;
00120 while (isdigit(ch)) {
00121 num = 10 * num + (ch-'0');
00122 ch = *nStr; nStr++;
00123 }
00124
00125
00126 while (isspace(ch)) {
00127 ch = *nStr; nStr++;
00128 }
00129
00130 long den;
00131 if (ch ==']') {
00132 den = 1;
00133 }
00134 else {
00135 do {
00136 ch = *nStr; nStr++;
00137 if (ch == '-') {
00138 es_positivo = !es_positivo;
00139 }
00140 } while (!isdigit(ch));
00141
00142
00143 den = 0;
00144 while (isdigit(ch)) {
00145 den = 10 * den + (ch-'0');
00146 ch = *nStr; nStr++;
00147 }
00148
00149 }
00150
00151
00152
00153 if (! es_positivo) {
00154 num = -num;
00155 }
00156 set( num, den );
00157 return *this;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 ostream& operator<< (ostream &COUT, const rational& r) {
00171 if ( r.m_den == 1 ) {
00172 return COUT << "[" << r.m_num << "]" ;
00173 } else {
00174 return COUT << "[" << r.m_num << "/" << r.m_den << "]" ;
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 istream& operator >> (istream &CIN, rational& r) {
00189 char ch;
00190
00191 bool es_positivo = true;
00192
00193
00194 do {
00195 CIN >> ch;
00196 if (ch == '-') {
00197 es_positivo = !es_positivo;
00198 }
00199 } while (!isdigit(ch));
00200
00201
00202 r.m_num = 0;
00203 while (isdigit(ch)) {
00204 r.m_num = 10 * r.m_num + (ch-'0');
00205 CIN >> ch;
00206 }
00207
00208
00209 while (isspace(ch)) {
00210 CIN >> ch;
00211 }
00212
00213 if (ch ==']') {
00214 r.m_den = 1;
00215 }
00216 else {
00217 do {
00218 CIN >> ch;
00219 if (ch == '-') {
00220 es_positivo = !es_positivo;
00221 }
00222 } while (!isdigit(ch));
00223
00224
00225 r.m_den = 0;
00226 while (isdigit(ch)) {
00227 r.m_den = 10 * r.m_den + (ch-'0');
00228 CIN >> ch;
00229 }
00230
00231
00232
00233
00234 while (ch != ']') {
00235 CIN >> ch;
00236 }
00237 }
00238
00239
00240
00241 if (! es_positivo) {
00242 r.m_num = -r.m_num;
00243 }
00244
00245 r.Simplify();
00246 return CIN;
00247
00248
00249
00250
00251
00252
00253
00254 }
00255
00256
00257
00258
00259 rational operator + (const rational &x, const rational &y) {
00260 long res_num, res_den;
00261 res_den = x.m_den * y.m_den;
00262 res_num = x.m_num * y.m_den + x.m_den * y.m_num;
00263
00264 return rational(res_num, res_den);
00265 }
00266
00267
00268
00269
00270 rational operator - (const rational &x, const rational &y) {
00271 long res_num, res_den;
00272
00273 res_den = x.m_den * y.m_den;
00274 res_num = x.m_num * y.m_den - x.m_den * y.m_num;
00275
00276 return rational(res_num, res_den);
00277 }
00278
00279
00280
00281
00282 rational operator * (const rational &x, const rational &y) {
00283 long res_num, res_den;
00284
00285 res_num = x.m_num * y.m_num;
00286 res_den = x.m_den * y.m_den;
00287
00288 return rational(res_num, res_den);
00289 }
00290
00291
00292
00293
00294
00295
00296 rational operator / (const rational &x, const rational &y) {
00297 long res_num, res_den;
00298 if (0 != y.m_num) {
00299 res_num = x.m_num * y.m_den;
00300 res_den = x.m_den * y.m_num;
00301 }
00302 return rational(res_num, res_den);
00303 }
00304
00305 CLOSE_namespace(ADH)
00306
00307