Você está na página 1de 7

UNMSM FII

ALGORITMOS Y PROGRAMACION

CASO ESTUDIO: EL TDA RACIONAL


NUMEROS RACIONALES
Los tipos numricos int y double son tiles para representar numricamente los enteros y los reales. Ocasionalmente esto no es suficiente; pues ninguno de estos tipos proporciona maneras de realizar una aritmtica exacta con datos numricos que posean parte fraccional. Aunque los double presentan nmeros con parte fraccional, su representacin es solo una aproximacin. De otro lado, la aritmtica de enteros es exacta y tipo int representa exactamente un entero. En el presente caso se trata de crear un tipo nmero racional (una clase), tal que incorpore la exactitud de los int y la caracterstica fraccional de los double. En matemticas un nmero racional es cualquier nmero real que puede ser expresado como el cociente de dos enteros. Son ejemplos de nmeros racionales: 17/5, 21/9, y 5/8. Los enteros son racionales puesto que pueden escribirse sobre 1; es decir, los nmeros 5 y 8 se pueden expresar como 5/1 y 8/1 respectivamente. Aunque algunos nmeros como 2 , , e, no se consideran nmeros racionales. Para ver los nmeros racionales desde un punto de vista matemtico debemos responder a las siguientes cuestiones: 1. Qu tipos de datos se requieren para, los nmeros racionales? 2. Qu tipos de operaciones estn definidas para estos datos? A la descripcin completa de ambos: los datos y las operaciones requeridas para ellos se le llama Tipo de Dato Abstracto (Abstract Data Type). Un TDA en ciencia de la computacin es un trmino basado en una idea matemtica llamada estructura algebraica. Una estructura algebraica consiste del dominio de objetos y las operaciones que se pueden realizar con esos objetos. Puede decirse que hasta aqu se ha llegado a nivel de diseo. El proceso que sigue consiste en definir el nuevo tipo en trminos de cdigo en un lenguaje de programacin. Resumiendo; en la construccin de un TDA, son necesarios dos pasos: primero, definir l o los tipos de datos, y segundo implementar dicho TDA como una clase. La implementacin se realiza con el lenguaje de programacin C++. La definicin de la clase racional se realiza en un archivo header llamado racional.h; y el archivo de prueba para la clase racional se escribe en el racional.cpp. A continuacin se muestra ambos listados.

ING. EDGAR RUIZ LIZAMA

UNMSM FII

ALGORITMOS Y PROGRAMACION

Racional

Racional() getnum() getdenom() +, -, *, / ==, <, <=, >, >=, != =, +=, -=, *=, /= ++, -<<, >> print()

Interface publica

num, denom simplificar()

Interface privada

Figura 1: El TDA Racional

//Archivo: racional.h #ifndef RACIONAL_H #define RACIONAL_H #include <iostream> #include <assert.h> using namespace std; int mcd(int, int); //para el maximo comun divisor class Racional{ public: //constructores Racional(int num=0, int denom=1); Racional(const Racional&); //atributos int getnum()const{return num;} int getdenom()const{return denom;} //operadores aritmeticos Racional operator-(); // menos unario friend Racional operator+(const Racional&, friend Racional operator-(const Racional&, friend Racional operator*(const Racional&, friend Racional operator/(const Racional&,

const const const const

Racional&); Racional&); Racional&); Racional&);

//operadores de comparacion friend bool operator==(const Racional&, const Racional&); friend bool operator!=(const Racional&, const Racional&); friend bool operator<(const Racional&, const Racional&); friend bool operator<=(const Racional&, const Racional&); friend bool operator>(const Racional&, const Racional&);

ING. EDGAR RUIZ LIZAMA

UNMSM FII

ALGORITMOS Y PROGRAMACION

friend bool operator>=(const Racional&, const Racional&); //operadores unarios Racional& operator++(); //incremento prefijo Racional& operator--(); //disminucion prefijo //operadores de asignacion Racional& operator=(const Racional&); Racional& operator+=(const Racional&); Racional& operator-=(const Racional&); Racional& operator*=(const Racional&); Racional& operator/=(const Racional&); //entrada salida void print(); friend ostream& operator<<(ostream&, const Racional&); friend istream& operator>>(istream&, Racional&); private: int num, denom; void simplificar(); }; Racional Racional :: operator-() { return Racional(-num, denom); } Racional operator+(const Racional& r1, const Racional& r2) { int dd = r1.denom*r2.denom; int nn = r1.num*r2.denom + r1.denom*r2.num; return Racional(nn,dd); } Racional operator-(const Racional& r1, const Racional& r2) { int dd = r1.denom*r2.denom; int nn = r1.num*r2.denom - r1.denom*r2.num; return Racional(nn,dd); } Racional operator*(const Racional& r1, const Racional& r2) { int dd = r1.denom*r2.denom; int nn = r1.num*r2.num; return Racional(nn,dd); } Racional operator/(const Racional& r1, const Racional& r2) { int dd = r2.num*r1.denom; int nn = r1.num*r2.denom; return Racional(nn,dd); }

ING. EDGAR RUIZ LIZAMA

UNMSM FII

ALGORITMOS Y PROGRAMACION

bool operator==(const Racional& r1, const Racional& r2) { return (r1.num*r2.denom == r1.denom*r2.num)?true:false; } bool operator!=(const Racional& r1, const Racional& r2) { return (r1.num*r2.denom != r1.denom*r2.num)?true:false; } bool operator<(const Racional& r1, const Racional& r2) { return (r1.num*r2.denom < r1.denom*r2.num)?true:false; } bool operator<=(const Racional& r1, const Racional& r2) { return (r1.num*r2.denom <= r1.denom*r2.num)?true:false; } bool operator>(const Racional& r1, const Racional& r2) { return (r1.num*r2.denom > r1.denom*r2.num)?true:false; } bool operator>=(const Racional& r1, const Racional& r2) { return (r1.num*r2.denom >= r1.denom*r2.num)?true:false; } Racional& Racional :: operator++() //prefijo { num = num + denom; return *this; } Racional& Racional :: operator--() //prefijo { num = num - denom; return *this; } Racional& Racional :: operator=(const Racional& p) { if ( *this != p) { num = p.num; denom = p.denom; } return *this; } Racional& Racional :: operator+=(const Racional& p) { *this = *this + p; return *this; }

ING. EDGAR RUIZ LIZAMA

UNMSM FII

ALGORITMOS Y PROGRAMACION

Racional& Racional :: operator-=(const Racional& p) { *this = *this-p; return *this; } Racional& Racional :: operator*=(const Racional& p) { *this = *this*p; return *this; } Racional :: Racional(int nu, int den) { assert(den != 0); num = nu; denom = den; simplificar(); } Racional :: Racional(const Racional& r) { num = r.num; denom = r.denom; } void Racional :: print() { cout<< *this; } ostream& operator<<(ostream& os, const Racional& r) { os<<r.num<<"/"<<r.denom; return os; } istream& operator>>(istream& is, Racional& r) { is>>r.num>>r.denom; return is; } void Racional :: simplificar() { if (!num) return; if (denom<0) { num = -num; denom = -denom; } int d = mcd(num,denom); if ( d > 1) { num = num/d; denom = denom/d; } }

ING. EDGAR RUIZ LIZAMA

UNMSM FII
int mcd(int x, int y) { if (x < y) return mcd(y,x); if( x%y == 0) return y; else return mcd(y, x%y); } #endif

ALGORITMOS Y PROGRAMACION

// fin de la libreria racional.h

//Archivo racional.cpp #include <stdio.h> #include "racional.h" using namespace std; int main() //racional.cpp { Racional r1(2,3), r2(1,2), r3(2,3), r4; cout<<"Numeros racionales"<<endl; cout<<"r1 = "<<r1<<endl; cout<<"r2 = "<<r2<<endl; cout<<"r3 = "<<r3<<endl; r4 = r1 + r2; cout<<"\nSuma de r1 y r2 = r4 -> "<<r4<<endl; if (r1 == r3) cout<<"\nr1 es igual a r3"<<endl; else cout<<"\nr1 no es igual a r3"<<endl; r4 += r1; cout<<"\nr4 = r4 + r1 -> "<<r4<<endl; r4 *= r2; cout<<"\nr4 = r4 * r2 -> "<<r4<<endl; ++r3; cout<<"\n1 + r3 = "<<r3<<endl; r1 = r4; cout<<"\nAsignando r4 a r1 -> "<<r1<<endl; cout<<"\nPresione una tecla..."; getchar(); return 0; }

La salida para el programa que utiliza la clase racional es como sigue

ING. EDGAR RUIZ LIZAMA

UNMSM FII

ALGORITMOS Y PROGRAMACION

Referencias: 1. 2. Perry Jo, Ellen and Levin Harold. An Introduction to ObjectOriented Design in C++ 1st edition, Addison Wesley Publishing Company, Inc. U.S.A. 1999. Deitel y Deitel, C++ How To Program 4th. Edition, Prentice Hall, Inc. U.S.A. 2003.
/ERL 2010

ING. EDGAR RUIZ LIZAMA

Você também pode gostar