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
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 bool check_ok( const rational& r ) {
00035 if (&r == 0) {
00036
00037 return false;
00038 }
00039
00040 if ( ! (r.m_den > 0) ) {
00041
00042 return false;
00043 }
00044 if (r.m_num == 0) {
00045 if ( r.m_den == 1 ) {
00046
00047 return true;
00048 }
00049 else {
00050 return false;
00051 }
00052 }
00053 if ( ! ( mcd(r.m_num, r.m_den) == 1 ) ) {
00054
00055 return false;
00056 }
00057 return true;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 bool check_ok_no_Rep( const rational& r ) {
00070 if (&r == 0) {
00071
00072 return false;
00073 }
00074
00075 if ( ! (r.den() > 0) ) {
00076
00077 return false;
00078 }
00079 if (r.num() == 0) {
00080 if ( r.den() == 1 ) {
00081
00082 return true;
00083 }
00084 else {
00085 return false;
00086 }
00087 }
00088 if ( ! ( mcd(r.num(), r.den()) == 1 ) ) {
00089
00090 return false;
00091 }
00092 return true;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 long mcd(long x, long y) {
00113 long g = (x < 0 ? -x : x);
00114 long r = (y < 0 ? -y : y);
00115 long temp;
00116
00117 do {
00118 temp = r;
00119 r = g % r;
00120 g = temp;
00121 } while (0 != r);
00122
00123 return g;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 void rational::Simplify() {
00138 if (m_num == 0) {
00139 m_den = 1;
00140 }
00141 long divisor = mcd(m_num, m_den);
00142 if (divisor > 1) {
00143 m_num /= divisor;
00144 m_den /= divisor;
00145 }
00146 if (m_den < 0) {
00147 m_num = -m_num;
00148 m_den = -m_den;
00149 }
00150 }
00151
00152
00153 rational& rational::operator += (const rational& otro) {
00154 m_num = m_num * otro.m_den + m_den * otro.m_num;
00155 m_den *= otro.m_den;
00156 Simplify();
00157
00158 return *this;
00159 }
00160
00161
00162
00163 rational& rational::operator -= (const rational& otro) {
00164 long oldm_den = m_den;
00165 long oldm_num = m_num;
00166 long d = otro.m_den;
00167 long n = otro.m_num;
00168
00169 m_den *= d;
00170 m_num = oldm_num * d - oldm_den * n;
00171 Simplify();
00172
00173 return *this;
00174 }
00175
00176
00177 rational & operator *= ( rational & a, const rational & b ) {
00178 a.set( a.num() * b.num(), a.den() * b.den() );
00179 return a;
00180 }
00181
00182
00183
00184 rational& rational::fromString (const char* nStr) {
00185 char ch;
00186
00187 bool es_positivo = true;
00188
00189
00190 do {
00191 ch = *nStr; nStr++;
00192 if (ch == '-') {
00193 es_positivo = !es_positivo;
00194 }
00195 } while (!isdigit(ch));
00196
00197
00198 long num = 0;
00199 while (isdigit(ch)) {
00200 num = 10 * num + (ch-'0');
00201 ch = *nStr; nStr++;
00202 }
00203
00204
00205 while (isspace(ch)) {
00206 ch = *nStr; nStr++;
00207 }
00208
00209 long den;
00210 if (ch ==']') {
00211 den = 1;
00212 }
00213 else {
00214 do {
00215 ch = *nStr; nStr++;
00216 if (ch == '-') {
00217 es_positivo = !es_positivo;
00218 }
00219 } while (!isdigit(ch));
00220
00221
00222 den = 0;
00223 while (isdigit(ch)) {
00224 den = 10 * den + (ch-'0');
00225 ch = *nStr; nStr++;
00226 }
00227
00228 }
00229
00230
00231
00232 if (! es_positivo) {
00233 num = -num;
00234 }
00235 set( num, den );
00236 return *this;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 std::ostream& operator<< (std::ostream &COUT, const rational& r) {
00248 if ( r.m_den == 1 ) {
00249 return COUT << "[" << r.m_num << "]" ;
00250 } else {
00251 return COUT << "[" << r.m_num << "/" << r.m_den << "]" ;
00252 }
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 std::istream& operator >> (std::istream &CIN, rational& r) {
00265 char ch;
00266
00267 bool es_positivo = true;
00268
00269
00270 do {
00271 CIN >> ch;
00272 if (ch == '-') {
00273 es_positivo = !es_positivo;
00274 }
00275 } while (!isdigit(ch));
00276
00277
00278 r.m_num = 0;
00279 while (isdigit(ch)) {
00280 r.m_num = 10 * r.m_num + (ch-'0');
00281 CIN >> ch;
00282 }
00283
00284
00285 while (isspace(ch)) {
00286 CIN >> ch;
00287 }
00288
00289 if (ch ==']') {
00290 r.m_den = 1;
00291 }
00292 else {
00293 do {
00294 CIN >> ch;
00295 if (ch == '-') {
00296 es_positivo = !es_positivo;
00297 }
00298 } while (!isdigit(ch));
00299
00300
00301 r.m_den = 0;
00302 while (isdigit(ch)) {
00303 r.m_den = 10 * r.m_den + (ch-'0');
00304 CIN >> ch;
00305 }
00306
00307
00308
00309
00310 while (ch != ']') {
00311 CIN >> ch;
00312 }
00313 }
00314
00315
00316
00317 if (! es_positivo) {
00318 r.m_num = -r.m_num;
00319 }
00320
00321 r.Simplify();
00322 return CIN;
00323
00324
00325
00326
00327
00328
00329
00330 }
00331
00332
00333
00334 rational operator + (const rational &x, const rational &y) {
00335 long res_num, res_den;
00336 res_den = x.m_den * y.m_den;
00337 res_num = x.m_num * y.m_den + x.m_den * y.m_num;
00338
00339 return rational(res_num, res_den);
00340 }
00341
00342
00343
00344 rational operator - (const rational &x, const rational &y) {
00345 long res_num, res_den;
00346
00347 res_den = x.m_den * y.m_den;
00348 res_num = x.m_num * y.m_den - x.m_den * y.m_num;
00349
00350 return rational(res_num, res_den);
00351 }
00352
00353
00354
00355 rational operator * (const rational &x, const rational &y) {
00356 long res_num, res_den;
00357
00358 res_num = x.m_num * y.m_num;
00359 res_den = x.m_den * y.m_den;
00360
00361 return rational(res_num, res_den);
00362 }
00363
00364
00365
00366
00367 rational operator / (const rational &x, const rational &y) {
00368 long res_num, res_den;
00369 if (0 != y.m_num) {
00370 res_num = x.m_num * y.m_den;
00371 res_den = x.m_den * y.m_num;
00372 }
00373 return rational(res_num, res_den);
00374 }
00375
00376 CLOSE_namespace(ADH)
00377
00378