Universidad de Costa Rica
Escuela de Ciencias de la
Computación e Informática
Profesor Adolfo Di Mare
CI-1201
I Semestre 2002
[<=] [home] [<>] [\/] [=>]
CI-1201 Programación II

Tarea #1 [solución]

Calculadora de números racionales

// racional.h  	(c) 2001 adolfo@di-mare.com

/*  resultado
    Implementa las operaciones aritméticas principales para la
    clase "racional" de números racionales.
*/

/*  programador: Adolfo Di Mare
*/

#ifndef racional_h
#define racional_h // evita la inclusión múltiple

#include <bool.h>  // elimine esta línea en compiladores nuevos

class ostream; class istream; // para operator << y operator >>

class racional {
private:
    long _num, _den; // numerador y denominador

    void simplifique();

public:
    // constructores
    racional() : _num(0), _den(1) { }  // constructor de vector
    racional(long num) : _num(num), _den(1) { }
    racional(long num, long _den)
        : _num(num), _den(_den) { simplifique(); }
    racional(const racional& o)       // constructor de copia
	{ _num = o._num, _den = o._den; }

    void asigne(long num=0, long den=1);  // nuevo valor

    racional& operator  = (const racional&);  // copia
    racional& operator  = (long);

    racional& operator += (const racional&);
    racional& operator -= (const racional&);
    racional& operator *= (const racional&);
    racional& operator /= (const racional&);

    racional operator  - ();			// menos unario

    friend racional operator + (const racional&, const racional&);
    friend racional operator - (const racional&, const racional&);
    friend racional operator * (const racional&, const racional&);
    friend racional 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&);
    friend bool operator >= (const racional&, const racional&);
    friend bool operator >  (const racional&, const racional&);

    friend ostream& operator << (ostream &, const racional& );
    friend istream& operator >> (istream &,       racional& );

    friend double real   (const racional& );   // Conversión a real
    friend long   integer(const racional& );   // Conversión a long

//  excluidos porque producen ambigüedad con operadores aritméticos
//  operator double () { return double(_num) / double(_den); }
//  operator long   () { return        _num  /        _den ; }
}; // racional

long mcd(long x, long y); // Calcula el Máximo Común Divisor

inline long gcd(long x, long y) { return mcd(x,y); }

inline void racional::asigne(long n, long d) {
/*  resultado
    Cambia el valor del número racional a "n/d".
*/
    _num = n;
    _den = d;
    simplifique();
}  // racional::asigne

inline racional& racional::operator = (const racional& o) {
// Copia

    _num = o._num,
    _den = o._den;

//  sobra invocar a "simplifique()" pues "o" ya está simplificado
    return *this;
}  // operator =

inline racional& racional::operator = (long entero) {
// Asiganción desde un "long"

    _num = entero;
    _den = 1;
    return *this;
}  // operator =

inline racional& racional::operator *= (const racional& num) {
// Operador de multiplicación

    _num *= num._num;
    _den *= num._den;
    simplifique();
    return *this;
}  // operator *=

inline racional& racional::operator /= (const racional& num) {
/*  resultado
    Divide a "*this" por el valor de "num".
*/
/*  requiere
    - (num != 0)
*/
    _num *= num._den;
    _den *= num._num;
    simplifique();
    return *this;
}  // operator /=

inline racional racional::operator - () {
// Menos unario

    racional tmp = (*this);
    tmp._num = - tmp._num;
    return tmp;
}  // operator -

inline bool operator == (const racional &x, const racional &y) {
    return (x._num == y._num) && (x._den == y._den);
}  // operator ==

inline bool operator < (const racional &x, const racional &y) {
    return (x._num * y._den) < (x._den * y._num);
}  // operator <

inline bool operator > (const racional &x, const racional &y) {
    return (y < x);
}  // operator >

inline bool operator != (const racional& x, const racional& y) {
    return !(x == y);
}  // operator !=

inline bool operator <= (const racional& x, const racional& y) {
    return !(y < x);
}  // operator <=

inline bool operator >= (const racional& x, const racional& y) {
    return !(x < y);
}  // operator >=

inline double real(const racional& num) {
// Convertidor a punto flotante
    return double (num._num) / double (num._den);
} // real()

inline long integer(const racional& num) {
// Convertidor a punto fijo
    return long   (num._num /          num._den);
} // integer()

#if 0
inline racional::operator long() {
// Convertidor a punto fijo
    return _num / _den;
}  // racional::operator long
#endif

#endif // racional_h

// EOF: racional.h
Figura 1: rational.h

      Con alguna frecuencia es necesario hacer aritmética con números racionales, para lo que conviene contar con una clase números racionales. En el siguiente artículo, disponible en Internet, se describe una implementación de la clase rational para el lenguaje Turbo Pascal:

Di Mare, Adolfo
"La Implementación de Rational.pas"; Reporte técnico ECCI-94-03; Proyecto 326-89-019; 1994.

      http://www.di-mare.com/adolfo/p/rational.htm
      http://www.di-mare.com/adolfo/p/src/rational.zip

/* p2-ta-1.cpp  (c) 2001 adolfo@di-mare.com */

#include <iostream.h>   // cin+cout
#include <iomanip>      // setw()
#include <climits>      // INT_MAX
#include "racional.h"   // racional

int main(void) {
/*  resultado
    <><><><><><><><> Qué hace el programa... */
/*  programador <><><><><><><><>
    Ponga aquí su nombre y carnet
    <><><><><><><><> */

    racional r,    // <><><><><><><><>
             acum; // <><><><><><><><>
    char op;       // <><><><><><><><>

    // <><><><><><><><>
    acum = 0;

    // <><><><><><><><>
    cout << acum << " > ";
    cin  >> op;


    // <><><><><><><><>
    while (op != '.') {
        // <><><><><><><><>
        cin >> r;             // <><><><><><><><>

        // <><><><><><><><>
        switch (op) {
            case '+': acum += r;          break;
            case '-': acum  = acum - r;   break;
            case '*': acum *= r;          break;
            case '/': acum  = acum / r;   break;
        default:
            // <><><><><><><><>
            cout << "\n(" << op << ")==> Operación inválida\n";
        }

        // <><><><><><><><>
        cout << acum << " > ";
        cin.ignore(INT_MAX, '\n');
        cin >> op;
    }

    // <><><><><><><><>
    return 0;
}  // main()

/* EOF: p2-ta-1.cpp */
Figura 2: Calculadora de números racionales

      Tome la implementación de la Figura 2, hágala funcionar y documéntela apropiadamente.

      Luego de imprimir la documentación de su programa, y entregarla en clase, envíe su trabajo por correo electrónico. Para esto, haga un archivo empacado .zip cuyo nombre sea su número de carnet. Incluya en ese archivo lo siguiente:

  1. Un documento en formato HTML que describa el trabajo que realizó. Incluya el nombre del compilador que usó.
  2. La especificación de su programa.
  3. El código fuente de su programa de prueba.
  4. Los datos de prueba para su programa.

      Las cuentas de computador en la ECCI se asignan de acuerdo al número de carnet. Por ejemplo, si su carnet es el número 95-28-09, para entregar su tarea usted debe crear el archivo 952809.zip para enviarlo por correo electrónico.

      Luego haga en su cuenta personal un subdirectorio llamado public_html, que es bajo el que se instalan todas sus páginas Internet. Por ejemplo, si su solución está en el archivo HTML llamado "OLP/t3sol952809.htm", entonces usted debe instalar esa página en el archivo
      public_html/OLP/t3sol952809.htm
de su cuenta. Luego, para acceder esa página Internet, debe entrar a este sitio:
      http://anubis.ecci.ucr.ac.cr/~e952809/OLP/t3sol952809.htm

      Como todas las cuentas de estudiante son la letra "e" seguida del número de carnet, para el estudiante de carnet "952809" la cuenta es "e952809". Para indicarle al servidor Internet a cuál cuenta entrar se usa el caracter "~" (Alt-126), seguido del nombre de la cuenta: "~e952809".

      Después de la fecha de entrega del programa, puede usted instalar en su cuenta personal su solución (no instale antes su solución en Internet, pues en ese caso sería usted culpable de facilitar la copia de su trabajo, y en consecuencia se haría acreedor a la sanción respectiva).

[mailto:] Entrega de Tareas

Tiempo de entrega: 1 semana
Segunda etapa: 3 días
Modalidad: Individual

Soluciones

[mailto:] Adolfo Di Mare <adolfo@di-mare.com>.
Copyright © 2002
Derechos de autor reservados © 2002
[home] <> [/\]