// IG17 2004-05, II17 2005-06 // Racional.cpp // 12-11-2004 #include using namespace std; #include "Racional.h" Racional::Racional (int n, int d) : numerador(n), denominador(d) { Normalizar(); } int MaximoComunDivisor (int a, int b) { // Calcula el maximo comun divisor de dos enteros positivos // empleando el algoritmo de Euclides while (b > 0) { int resto = a % b; a = b; b = resto; } return a; } void Racional::Normalizar () { int signo, mcd; if(numerador == 0 && denominador == 0) // Caso 0/0: se deja asi return; if (numerador == 0) { // Caso 0/d: se deja como 0/1 denominador = 1; return; } if (denominador == 0) { // Caso n/0: se deja como 1/0 o -1/0 if (numerador > 0) numerador = 1; else numerador = -1; return; } // Caso n/d general: se divide numerador y denominador entre su // maximo comun divisor y, si el racional es negativo, se pone // el signo en el numerador if (numerador * denominador > 0) signo = 1; else signo = -1; if (denominador < 0) denominador = -denominador; if (numerador < 0) numerador = -numerador; mcd = MaximoComunDivisor(numerador, denominador); numerador /= mcd; denominador /= mcd; numerador *= signo; } bool operator== (Racional r1, Racional r2) { return r1.numerador == r2.numerador && r1.denominador == r2.denominador; } bool operator!= (Racional r1, Racional r2) { return !(r1==r2); } Racional operator+ (Racional r1, Racional r2) { if (r1.numerador != 0 && r1.denominador == 0 && r2 == r1) return r1; // Asi 1/0 + 1/0 da 1/0 y -1/0 + -1/0 da -1/0 else // Los demas casos especiales funcionan bien con la formula general return Racional(r1.numerador * r2.denominador + r1.denominador * r2.numerador, r1.denominador * r2.denominador); } Racional operator* (Racional r1, Racional r2) { return Racional(r1.numerador * r2.numerador, r1.denominador * r2.denominador); } Racional & Racional::operator+= (Racional r) { *this = *this + r; return *this; } Racional & Racional::operator*= (Racional r) { *this = *this * r; return *this; } Racional Racional::operator- () const { return Racional (-numerador, denominador); } Racional & Racional::operator++ () { return *this += 1; } Racional Racional::operator++ (int) { Racional valorAnterior = *this; *this += 1; return valorAnterior; } ostream & operator<< (ostream & flujo, Racional r) { flujo << r.numerador << '/' << r.denominador; return flujo; } istream & operator>> (istream &flujo, Racional & r) { char separador; flujo >> r.numerador >> separador >> r.denominador; r.Normalizar(); return flujo; }