Universidad de Costa Rica
Ciencias de
Curso:
Programación II
Documentación
II tarea Programada
Profesor: Adolfo Di-Mare
Alumnos:
Elsie Castro Villalobos A41369
Armando Soto Rodríguez A55609
30/08/2007
Índice
Dirección
Internet en dónde está la documentación:
Descripción
del problema a resolver:
Formato de los
datos de prueba
Entradas vs
Salidas esperadas:
El
siguiente trabajo a realizar se basa en la utilización de plantillas para la
fabricación de clases, con lo cual se puede emplear el programa utilizando
diferente tipos de clases, como por ejemplo los tipos básicos: short, int,
long, long long.
La idea de
emplantillar clases es sumamente importante para la reutilización de módulos
disponibles, lo cual disminuye el tiempo de fabricación de programas.
http://www.geocities.com/elsiecv21/Documentacion2.htm
http://www.geocities.com/arsoro1986/Tarea2.htm
Usar una clase ya implementada para obtener un
clase equivalente, pero emplantillada. La idea es construir nuevas piezas de
programación con base en las ya existentes para aprovechar los módulos
disponibles.
Tomar la implementación de la clase rational que
le fue entregada en clase y mejórela para que sea posible crear números
racionales a partir de enteros cortos o largos, o a partir de otras clases
aritmética.
La
clase racional sirve para definir un número racional y así poder realizar
operaciones matemáticas básicas con los mismos; suma, resta multiplicación y
división, además esta clase esta emplantillada lo cual permite definir un
racional a base de diferentes tipos de clases como por ejemplo: short, int,
long.
void Simplify(): Simplifica
la fracción para que \c m_num y \c m_den sean números primos relativos.
void set(INT num=0, INT den=1)
Le cambia el valor a *this
INT num() const { return m_num; }
Copia del numerador
INT den() const { return m_den; }
Copia del denominador
rational& operator = (const
rational&): Asignación
de copia; copia desde "o", el valor anterior de "*this" se
pierde.
rational& operator = (INT): Asignación
desde un "long".
rational& swap ( rational& ): Intercambia los valores de "*this" y "o".
rational& operator +=
(const rational&): Le suma a "*this" el valor de "otro".
rational& operator -=
(const rational&): Le resta a "*this" el valor de "otro".
rational& operator *=
(const rational&): Multiplica "*this" por "num".
rational& operator /=
(const rational&): Divide "*this" por el valor de "num".
rational operator - () const: Calcula y retorna el valor "-x".
friend rational<T> operator +
(const rational<T>&, const rational<T>&): Calcula y retorna la suma "x+y".
friend rational<T> operator -
(const rational<T>&, const rational<T>&): Calcula y retorna la resta "x-y".
friend rational<T> operator *
(const rational<T>&, const rational<T>&): Calcula y retorna la multiplicación "x*y".
friend rational<T> operator /
(const rational<T>&, const rational<T>&): Calcula y retorna la división "x/y".
friend bool operator == (const
rational<T>&, const
rational<T>&): compara dos
numeros racionales x == y
friend bool operator
< (const
rational<T>&, const
rational<T>&):
compara si un
racional es menor a otro x < y
friend bool operator != (const rational<T>&, const rational<T>&):
compara si un
racional es disferente de otro x != y
friend bool operator <= (const rational<T>&, const rational<T>&):
compara si un
racional es menor o igual a otro x <= y
friend bool operator >= (const rational<T>&, const rational<T>&):
compara si un
racional es mayor o igual a otro x >= y
friend bool operator
> (const
rational<T>&, const rational<T>&):
compara si un
racional es mayor a otro x > y
friend ostream& operator
<< (ostream &, const
rational<T>& ): Graba el valor
de "r" en el flujo "COUT".
friend istream& operator
>> (istream &, rational<T>& ): Lee del flujo de texto "CIN" el valor de "r".
rational& fromString (const
char* nStr): Establece el varlor de "*this" a partir de la hilera
"nStr".
friend double real (const rational<T>& ): Conversión a real.
friend INT integer(const
rational<T>& ): Conversión a
long.
friend bool check_ok( const
rational<T>& r ): Revisa la
invariante.
El programa
realiza operaciones básicas, suma, resta, multiplicación, división y
comparaciones ( = =, <, >, < =,
> =, !=) con los números racionales, ademas de mostrar el resultado en su
forma canonica.
-Ningún
objeto puede estar almacenado en la posición nula.
-El
denominador debe ser un número positivo.
-El
cero debe representarse con denominador igual a "1".
-El
numerador y el denominador deben ser primos relativos.
Visual
Studio 2005
Abrir
el proyecto y darle click en la opción build, build rat-calc.
Al
iniciar el programa los números racionales se ingresan de la siguiente manera: [ 5/6 ] .
Se utilizaran
los operadores matemáticos básicos para la realización de los diferentes
cálculos requeridos.
Por ejemplo:
[0] > + [ 2 / 3 ]
[2/3] > / [ 6 / 2 ] [2/9] > * [ 18 ] [4] > - [ 45 / 9 ] [-1] > / [ 13 / 8 ] [-8/13] > * [ 2 ] [-16/13] > + [ 7 ] [75/13] > . [75/13] >
Para
terminar el programa solamente ingrese un punto cuando lo crea conveniente.
Los datos deberán ser ingresados
de la siguiente manera:
[0] > + [ 2 / 3 ]
[2/9] > * [ 18 ] [-1] > / [ 13 / 8 ] [75/13] > .
Utilizando
la clase con el tipo long:

Utilizando la clase con el tipo int:

Utilizando la clase con el tipo short:

#ifndef rational_h
#define rational_h
///< Evita la inclusión múltiple
#include "ADH_port.h"
#include <iostream>
using namespace std;
/**
La clase \c rational implementa las operaciones aritméticas
principales para números rationales.
- <code> [1/3] == [2/6] ==
... [9/27] == ... </code>
- <code> [1/3] * [2/6] / [3/9] - [9/27] </code>
*/
template <class INT>
class rational {
private:
INT m_num; ///<
Numerador
INT m_den; ///< Denominador
void Simplify();
public:
// constructores
rational() :
m_num(0), m_den(1) { } ///< Constructor de vector
rational(INT
num) : m_num(num), m_den(1) { } ///< Constructor a
partir de un valor entero
rational(INT
num, INT den)
:
m_num(num), m_den(den) { Simplify(); } ///<
Constructor a partir de un valor quedbrado
rational(const rational& o) ///
Constructor de copia
{ m_num =
o.m_num, m_den = o.m_den; }
~rational() { } ///<
Destructor
void
set(INT num=0, INT den=1); // Le cambia el valor a \c "*this"
INT num() const
{ return m_num; } ///< Copia del
numerador
INT den() const { return m_den;
} ///<
Copia del denominador
// void num(long n) { m_num=n;
Simplify(); } // FEO
// void den(long d) { m_den= ( d!=0
? d : m_den) ; Simplify(); } // FEO
rational& operator = (const
rational&); //
Asignación (copia)
rational& operator = (INT);
rational& swap ( rational& );
rational& operator
+= (const rational&);
rational& operator
-= (const rational&);
rational& operator
*= (const rational&);
rational& operator
/= (const rational&);
rational operator - () const; // menos
unario
template
<class T> friend
rational<T> operator + (const rational<T>&, const rational<T>&);
template
<class T> friend
rational<T> operator - (const rational<T>&, const rational<T>&);
template
<class T> friend
rational<T> operator * (const rational<T>&, const rational<T>&);
template
<class T> friend
rational<T> operator / (const rational<T>&, const rational<T>&);
template
<class T> friend
bool operator
== (const rational<T>&, const rational<T>&);
template
<class T> friend
bool operator
< (const
rational<T>&, const
rational<T>&);
template
<class T> friend
bool operator
!= (const rational<T>&, const rational<T>&);
template
<class T> friend
bool operator
<= (const rational<T>&, const rational<T>&);
template
<class T> friend
bool operator
>= (const rational<T>&, const rational<T>&);
template
<class T> friend
bool operator
> (const
rational<T>&, const
rational<T>&);
template
<class T> friend
ostream& operator << (ostream &, const rational<T>& );
template
<class T> friend
istream& operator >> (istream
&, rational<T>& );
rational& fromString (const char* nStr);
template
<class T> friend
double real
(const rational<T>& ); // Conversión a
real
template
<class T> friend
INT integer(const
rational<T>& ); // Conversión a long
template
<class T> friend
bool check_ok( const
rational<T>& r ); // Ok()
//
excluidos porque producen ambigüedad con operadores aritméticos
// operator double () { return
double(m_num) / double(m_den); }
// operator long () { return m_num
/ m_den ; }
}; // rational
template <class INT>
INT mcd(INT x, INT y); //
Calcula el Máximo Común Divisor
/// Sinónimo de \c mcd(x,y) <code> [ inline ] </code>
template <class INT>
inline INT
gcd(INT x, INT y) { return mcd(x,y); }
/// Cambia el valor del número rational
a \c "n/d"
template <class INT>
inline void rational<INT>::set(INT n, INT d) {
m_num = n;
m_den = d;
Simplify();
}
/** Copia desde \c "o".
- El valor anterior de \c "*this" se pierde.
\par Complejidad:
O( \c 1 )
\returns *this
\see
http://www.di-mare.com/adolfo/binder/c04.htm#sc05
*/
template <class INT>
inline
rational<INT>& rational<INT>::operator
= (const rational<INT>& o) {
m_num = o.m_num,
m_den = o.m_den;
//
sobra invocar a "Simplify()" pues "o" ya está
simplificado
return *this;
} // operator =
/** Intercambia los valores de \c
"*this" y \c "o".
\par Complejidad:
O( \c 1 )
\returns *this
\see
http://www.di-mare.com/adolfo/binder/c04.htm#sc08
*/
template <class INT>
inline
rational<INT>& rational<INT>::swap ( rational<INT>& o
) {
#if 1
rational tmp = o;
o = *this;
*this = tmp;
#else
// Esto NO funciona para objetos, métodos virtuales, etc.
char tmp[ sizeof( *this ) ];
memcpy( tmp, o,
sizeof( *this ) ); // tmp = o;
memcpy( o, *this,
sizeof( *this ) ); // o = *this;
memcpy( *this, tmp, sizeof( *this ) ); // *this = tmp;
#endif
return *this;
}
/// Asignación desde un \c "long".
template <class INT>
inline
rational<INT>& rational<INT>::operator
= (INT entero) {
m_num =
entero;
m_den = 1;
return *this;
} // operator =
/// Multiplica \c "*this" por \c "num".
template <class INT>
inline
rational<INT>& rational<INT>::operator
*= (const rational<INT>& num) {
m_num *= num.m_num;
m_den *=
num.m_den;
Simplify();
return *this;
} // operator *=
/** Divide \c "*this" por
el valor de \c "num".
\pre
- (num != 0)
*/
template <class INT>
inline
rational<INT>& rational<INT>::operator
/= (const rational<INT>& num) {
m_num *= num.m_den;
m_den *= num.m_num;
Simplify();
return *this;
} // operator /=
/// \c "-x".
/// - Menos unario
/// - Calcula y retorna el valor \c
"-x"
template <class INT>
inline
rational<INT> rational<INT>::operator
- () const {
rational tmp = (*this); // tmp.rational(
*this );
tmp.m_num = - tmp.m_num;
return tmp;
} // operator -
/// ¿ x == y ?
template <class INT>
inline bool operator == (const rational<INT> &x, const rational<INT> &y) {
return
(x.m_num == y.m_num) && (x.m_den == y.m_den);
/*
Nota:
Como los números racionales siempre están simplificados, no puede
ocurrir que [1/1] está almacenado como [3/3] y en consecuencia
basta comparar los valores campo por campo para determinar si se
da o no la igualdad.
*/
} // operator ==
/// ¿ x < y ?
template <class INT>
inline bool operator < (const rational<INT> &x, const rational<INT> &y) {
return
(x.m_num * y.m_den) < (x.m_den * y.m_num);
/*
Nota:
Una desigualdad de fracciones se preserva siempre que se
multiplique a ambos lados por un número positivo. Por eso:
[a/b] < [c/d] <==>
[(b*d)*a/b] < [(b*d)*c/d] <==>
[d*a] < [b*c]
[a/b] > [c/d] <==>
[(b*d)*a/b] > [(b*d)*c/d] <==> [d*a] > [b*c]
Debido a que el denominador siempre es un número positivo,
el
trabajo de comparar 2 racionales se puede lograr haciendo 2
multiplicaciones de números enteros, en lugar de convertirlos
a punto flotante para hacer la división, que es hasta un orden
de magnitud más lento.
*/
// return double(x.m_num) /
double(x.m_den) < double(y.m_num) / double(y.m_den);
} // operator <
/// ¿ x > y ?
template <class INT>
inline bool operator > (const rational<INT> &x, const rational<INT> &y) {
return (y < x);
} // operator >
/// ¿ x != y ?
template <class INT>
inline bool operator != (const rational<INT>& x, const rational<INT>& y) {
return !(x == y);
} // operator !=
/// ¿ x <= y ?
template <class INT>
inline bool operator <= (const rational<INT>& x, const rational<INT>& y) {
return !(y < x);
} // operator <=
/// ¿ x >= y ?
template <class INT>
inline bool operator >= (const rational<INT>& x, const rational<INT>& y) {
return !(x < y);
} // operator >=
/// Convertidor a punto flotante.
template <class INT>
inline double real(const
rational<INT>& num) {
return double (num.m_num) / double
(num.m_den);
} // real()
/// Convertidor a punto fijo.
template <class INT>
inline INT
integer(const rational<INT>& num) {
return
INT (num.m_num / num.m_den);
} // integer()
#if 0
/// Convertidor a punto fijo
inline rational::operator INT() {
return INT (m_num / m_den);
} //
rational::operator long
#endif
template <class INT>
bool
check_ok_externo( const
rational<INT>& r );
#include <cstdlib>
#include <cctype> // isdigit()
/** Verifica la invariante de la clase
\c rational.
\par <em>Rep</em> Modelo de la clase:
\code
+---+
| 3 | <== m_num == numerador
del número racional
+---+
|134| <== m_den == denominador
del número racional
+---+
\endcode
-
http://www.di-mare.com/adolfo/binder/c03.htm#k1-Rep
\remark
Libera al programador de implementar el método \c Ok()
- http://www.di-mare.com/adolfo/binder/c04.htm#sc11
*/
template <class INT>
bool check_ok( const rational<INT>& r ) {
if (&r == 0) {
/// - Invariante: ningún objeto puede estar almacenado en
la posición nula.
return false;
}
if ( !
(r.m_den > 0) ) {
/// - Invariante: el denominador debe ser un número positivo.
return false;
}
if (r.m_num
== 0) {
if ( r.m_den == 1 ) {
/// - Invariante: el cero debe representarse con
denominador igual a "1".
return true;
}
else {
return
false;
}
}
if ( ! (
mcd(r.m_num, r.m_den) == 1 ) ) {
/// - Invariante: el numerador y el denominador deben ser primos
relativos.
return false;
}
return true;
} // check_ok()
/** Verifica la invariante de la clase
\c rational.
\remark
Esta implementación nos se le mete al <em>Rep</em>
(casi siempre no es posible implementar una función como ésta).
- http://www.di-mare.com/adolfo/binder/c03.htm#k1-Rep
\remark
Libera al programador de implementar el método \c Ok()
- http://www.di-mare.com/adolfo/binder/c04.htm#sc11
*/
template <class INT>
bool
check_ok_no_Rep( const rational<INT>&
r ) {
if (&r == 0) {
/// - Invariante: ningún objeto puede estar almacenado en
la posición nula.
return false;
}
if ( !
(r.den() > 0) ) {
/// - Invariante: el denominador debe ser un número positivo.
return false;
}
if (r.num() == 0) {
if ( r.den() == 1 ) {
/// - Invariante: el cero debe representarse con
denominador igual a "1".
return true;
}
else {
return
false;
}
}
if ( ! (
mcd(r.num(), r.den()) == 1 ) ) {
/// - Invariante: el numerador y el denominador deben ser primos
relativos.
return false;
}
return true;
} // check_ok_no_Rep()
/** Calcula el Máximo Común Divisor de
los números \c "x" y \c "y".
- <code> mcd(x,y) >= 1 </code> siempre.
- MCD <==> GCD: <em> Greatest Common
Divisor </em>.
\pre
<code> (y != 0) </code>
\remark
Se usa el algoritmo de Euclides para hacer el cálculo.
\par Ejemplo:
\code
2*3*5 == mcd( 2*2*2*2 * 3*3 * 5*5, 2*3*5 )
30 == mcd( -3600, -30 )
\endcode
*/
template <class INT>
INT mcd(INT
x, INT y) {
INT g = (x
< 0 ? -x : x); // trabaja con valores positivos
INT r = (y <
0 ? -y : y); // "r" es el resto
INT temp;
do {
temp = r;
r
= g % r;
g
= temp;
} while (0
!= r);
return g;
} // mcd()
/** Simplifica el numerador y el
denomidador.
- Transforma el número rational de manera que el numerador y el
denominador sean primos relativos, asegurando además que el
denominador es siempre positivo.
- Si <code>(m_num==0) ==> (m_den==1)</code>.
- Simplifica la fracción para que \c m_num y \c m_den sean números
primos relativos ie, <code>mcd(m_num,m_den) == 1</code>.
- Asegura que \c m_den sea un número positivo.
- Restaura la invariante de la clase \c rational.
*/
template <class INT>
void
rational<INT>::Simplify() {
if (m_num
== 0) {
m_den = 1;
}
INT divisor = mcd(m_num, m_den);
if (divisor
> 1) { //
==> (divisor != 0)
m_num /= divisor;
m_den /= divisor;
}
if (m_den
< 0) {
m_num =
-m_num;
m_den =
-m_den;
}
} // rational::Simplify()
/// Le suma a \c "*this" el
valor de \c "otro".
template <class INT>
rational<INT>&
rational<INT>::operator += (const rational<INT>& otro) {
m_num = m_num * otro.m_den + m_den * otro.m_num;
m_den *=
otro.m_den;
Simplify();
return *this;
} // operator +=
/// Le resta a \c "*this" el
valor de \c "otro".
template <class INT>
rational<INT>&
rational<INT>::operator -= (const rational<INT>& otro) {
INT oldm_den = m_den;
INT oldm_num = m_num;
INT d
= otro.m_den;
INT n
= otro.m_num;
m_den *= d;
m_num = oldm_num * d - oldm_den * n;
Simplify();
return *this;
} // operator -=
/// Establece el varlor de \c
"*this" a partir de la hilera \c "nStr".
/// \pre \c "nStr" debe estar
escrita en el formato "[num/den]".
template <class INT>
rational<INT>&
rational<INT>::fromString (const char* nStr) {
char ch; // valor obtenido, caracter por caracter, de
"nStr"
bool es_positivo = true; // manejo de los
signos + y -
// se brinca todo hasta el primer dígito
do {
ch = *nStr;
nStr++;
if (ch == '-')
{ // cambia de
signo
es_positivo = !es_positivo;
}
} while (!isdigit(ch));
// se traga el numerador
INT num = 0;
while (isdigit(ch)) { //
convierte a decimal: izq --> der
num = 10 *
num + (ch-'0');
ch = *nStr;
nStr++;
}
// se brinca los blancos después del numerador
while
(isspace(ch)) {
ch = *nStr; nStr++;
}
INT den;
if (ch ==']') { // es un número entero
den = 1;
}
else {
do { // se brinca todo hasta el denominador
ch = *nStr;
nStr++;
if
(ch == '-') {
es_positivo = !es_positivo;
}
} while (!isdigit(ch));
// se traga el denominador
den = 0;
while
(isdigit(ch)) {
den = 10 * den + (ch-'0');
ch = *nStr; nStr++;
}
// Ya no importa si aparece o no el ']' del final del
número
}
// le cambia el signo, si hace falta
if (! es_positivo) {
num = -num;
}
set( num, den );
return *this;
}
/** Graba el valor de \c "r"
en el flujo \c "COUT".
- Graba el valor en el formato [num/den].
- En particular, este es el operador que se invoca
cuando se usa, por ejemplo, este tipo de instrucción:
\code
cout << r <<
q;
\endcode
*/
template <class INT>
ostream&
operator<< (ostream &COUT, const rational<INT>& r) {
if ( r.m_den == 1 ) { // no hay
parte fraccional
return COUT
<< "[" << r.m_num
<< "]" ;
} else {
return
COUT << "[" << r.m_num
<< "/" << r.m_den
<< "]" ;
}
} // operator <<
/** Lee del flujo de texto \c
"CIN" el valor de \c "r".
\pre
El número rational debe haber sido escrito usando
el formato "[r/den]", aunque es permisible usar
algunos blancos.
- Se termina de leer el valor sólo cuando encuentra \c "]".
- <code> [ -+-+-+-+- 4 / -- -+ -- 32 ] </code> se lee como
<code> [1/8] </code>
*/
template <class INT>
istream&
operator >> (istream &CIN,
rational<INT>& r) {
char ch; // valor leido, letra por letra, de "CIN"
bool es_positivo = true; // manejo de los
signos + y -
// se brinca todo hasta el primer dígito
do {
CIN >>
ch;
if (ch == '-')
{ // cambia de
signo
es_positivo = !es_positivo;
}
} while (!isdigit(ch));
// se traga el numerador
r.m_num = 0;
while (isdigit(ch)) { //
convierte a decimal: izq --> der
r.m_num =
10 * r.m_num + (ch-'0');
CIN
>> ch;
}
// se brinca los blancos después del numerador
while
(isspace(ch)) {
CIN >> ch;
}
if (ch ==']') { // es un número entero
r.m_den = 1;
}
else {
do { // se brinca todo hasta el denominador
CIN
>> ch;
if
(ch == '-') {
es_positivo = !es_positivo;
}
} while (!isdigit(ch));
// se traga el denominador
r.m_den = 0;
while
(isdigit(ch)) {
r.m_den = 10 * r.m_den + (ch-'0');
CIN >> ch;
}
// El programa se duerme si en el flujo de entrada
// NO aparece el caracter delimitador final "]",
// pues la lectura termina hasta encontrar el
"]".
while (ch != ']') {
CIN >> ch;
}
} // corrección:
Andrés Arias <[email protected]>
// le cambia el signo, si hace falta
if (!
es_positivo) {
r.m_num = -r.m_num;
}
r.Simplify();
return CIN;
/*
no detecta errores...
[1/0] lo lee y no se queja
[ !#!#!$#@! 3/ aaaa 4 jajaja ] lo lee como 3/4
... pero no se supone que el usuario cometa errores...
*/
} // operator >>
/// \c "x+y".
/// - Calcula y retorna la suma \c
"x+y".
template <class INT>
rational<INT>
operator + (const
rational<INT> &x, const
rational<INT> &y) {
INT res_num, res_den;
res_den = x.m_den * y.m_den;
res_num = x.m_num * y.m_den + x.m_den *
y.m_num;
return
rational<INT>(res_num, res_den);
} // operator + ()
/// \c "x-y".
/// - Calcula y retorna la resta \c
"x-y".
template <class INT>
rational<INT>
operator - (const
rational<INT> &x, const
rational<INT> &y) {
INT res_num, res_den;
res_den = x.m_den * y.m_den;
res_num = x.m_num * y.m_den - x.m_den *
y.m_num;
return
rational<INT>(res_num, res_den);
} // operator - ()
/// \c "x*y".
/// - Calcula y retorna la
multiplicación \c "x*y".
template <class INT>
rational<int> operator * (const rational<INT> &x, const rational<INT> &y) {
INT res_num, res_den;
res_num = x.m_num * y.m_num;
res_den = x.m_den * y.m_den;
return
rational<INT>(res_num, res_den);
} // operator * ()
/// \c "x/y".
/// - Calcula y retorna la división \c
"x/y".
/// \pre <code> y != 0 </code>
template <class INT>
rational<INT>
operator / (const
rational<INT> &x, const
rational<INT> &y) {
INT res_num, res_den;
if (0 !=
y.m_num) {
res_num
= x.m_num * y.m_den;
res_den =
x.m_den * y.m_num;
}
return
rational<INT>(res_num, res_den);
} // operator / ()
#endif // rational_h
// EOF: rational.h
#ifndef ADH_port_h
#define ADH_port_h ///< Evita la
inclusión múltiple
// Documentados acá para Doxygen
#undef CLOSE_namespace
#undef USING_namespace
#undef OPEN_namespace
/// Abre namespace \c
"N"
#define
OPEN_namespace(N) namespace N {
/// Cierra namespace \c "N"
#define CLOSE_namespace(N) }
/// Usa namespace \c "N"
#define
USING_namespace(N) using namespace N
// Los anula para luego definirlos
dentro del #ifdef correcto
#undef CLOSE_namespace
#undef USING_namespace
#undef OPEN_namespace
#ifdef DOXYGEN_COMMENT // Documentados acá para Doxygen
/// Definido por la biblioteca C++ estándar
namespace std {} // Está acá para que Doxygen lo documente
/// ADH son las siglas de \c [email protected]
namespace ADH {} // Está acá para que Doxygen lo documente
#define INCLUDE_fstream Truco para "include
<fstream>" portable
#define
INCLUDE_io Truco para
"include <io>"
portable
#define INCLUDE_iomanip Truco
para "include <iomanip>"
portable
#define INCLUDE_iostream Truco
para "include <iostream>"
portable
#define INCLUDE_list Truco
para "include <list>"
portable
#define INCLUDE_map Truco
para "include <map>"
portable
#define INCLUDE_stdexcept Truco para "include
<stdexcept>" portable
#define INCLUDE_vector Truco
para "include <vector>"
portable
#endif
// Borland C++
#ifdef __BORLANDC__
///< Definida para Borland C++
#if (__BORLANDC__ <= 0x0410)
// Identifica a BC++ v3.1 y
anterior
// Declara el tipo "bool" porque BC++ v3.1 NO tiene
"bool"
#ifndef _bool_h
#define _bool_h
#undef false
#undef true
#undef bool
typedef int bool;
const int false = 0;
const int true = ! false; //
#endif
class istream; class ostream;
#define using //
#define namespace
#define std
#define ADH
#define OPEN_namespace(N) //
#define CLOSE_namespace(N)
#define USING_namespace(N)
#ifdef INCLUDE_fstream
#include <fstream.h>
#endif
#ifdef INCLUDE_io
#include <io.h>
#endif
#ifdef INCLUDE_iomanip
#include <iomanip.h>
#endif
#ifdef INCLUDE_iostream
#include <iostream.h>
#endif
#ifdef INCLUDE_list
#include <list.h>
#endif
#ifdef INCLUDE_map
#include <map.h>
#endif
#ifdef INCLUDE_set
#include <set.h>
#endif
#ifdef INCLUDE_stdexcept
#include <stdexcept.h>
#endif
#ifdef INCLUDE_string
#include <string.h>
#endif
#ifdef INCLUDE_vector
#include <vector.h>
#endif
#endif
#if (__BORLANDC__ > 0x0410)
// Versiones posteriores a
#define OPEN_namespace(N) namespace N {
#define CLOSE_namespace(N) }
#define USING_namespace(N) using
namespace N
#error Ajuste ADH_port.h para compìlar con versiones nuevas de BC++
#endif
#endif
// Microsoft C++ (Visual Studio)
#ifdef _MSC_VER
///< Definida para Micrsoft C++
// namespace
#define
OPEN_namespace(N) namespace N {
#define
CLOSE_namespace(N) }
#define
USING_namespace(N) using namespace N
#if (_MSC_VER >= 1300) // Identifica a VC++ .net
/// Definido por la biblioteca C++ estándar
namespace std {} // Está
acá para que Doxygen lo documente
using namespace std;
#ifdef
INCLUDE_fstream
#include <fstream>
#endif
#ifdef
INCLUDE_io
#include <io>
#endif
#ifdef
INCLUDE_iomanip
#include <iomanip>
#endif
#ifdef
INCLUDE_iostream
#include <iostream>
#endif
#ifdef
INCLUDE_list
#include <list>
#endif
#ifdef
INCLUDE_map
#include <map>
#endif
#ifdef
INCLUDE_set
#include <set>
#endif
#ifdef
INCLUDE_stdexcept
#include <stdexcept>
#endif
#ifdef
INCLUDE_string
#include <string>
#endif
#ifdef
INCLUDE_vector
#include
<vector>
#endif
#endif
#if (_MSC_VER < 1300) // Identifica a VC++ v6 y anterior
namespace std {} // Está acá para que Doxygen lo documente
using namespace std;
// Antes de MSC++ .NET hay que usar <.h>
#ifdef INCLUDE_fstream
#include <fstream.h>
#endif
#ifdef INCLUDE_io
#include <io.h>
#endif
#ifdef INCLUDE_iomanip
#include <iomanip.h>
#endif
#ifdef INCLUDE_iostream
#include <iostream.h>
#endif
#ifdef INCLUDE_list
#include <list.h>
#endif
#ifdef INCLUDE_map
#include <map.h>
#endif
#ifdef INCLUDE_set
#include <set.h>
#endif
#ifdef INCLUDE_stdexcept
#include <stdexcept.h>
#endif
#ifdef INCLUDE_string
#include
<string.h>
#endif
#ifdef INCLUDE_vector
#include <vector.h>
#endif
#endif
#endif
#endif // ADH_port_h
// EOF: ADH_port.h
#include "rational.h"
#include <limits.h>
/// Función principal en la que empieza
la ejecución del programa
//template <class INT>
int main() {
rational<int> r,
// último valor ingresado
acum; //
acumulador de la calculadora
char
op; //
operación a efectuar
// inicializa el acumudador
acum = 0;
// despliega el valor inicial del acumulador
cout <<
acum << " > ";
cin >> op;
// ciclo para leer la siguiente operación a efectuar
while (op != '.') {
// valor a operar con el acumulador
cin >> r; //
operator>> (cin, r);
// selección de la operación a realizar
switch (op) {
case
'+': acum += r; break;
// acum.op += ( r );
case
'-': acum
= acum - r; break; // acum.op = (op- (acum, r));
case
'*': acum *= r; break;
// acum.op *= ( r );
case
'/': acum
= acum / r; break; // acum.op = (op/ (acum, r));
default:
// operación inválida
cout
<< "\n(" << op <<
")==> Operación inválida\n";
}
// despliega el nuevo valor del acumulador
cout
<< acum << " > ";
cin.ignore(INT_MAX, '\n');
cin
>> op;
}
// despliega el valor final del acumulador
cout
<< acum << " > ";
return 0;
}
// main()
http://di-mare.com/pub/pg2/00-Material-CI-1201.htm
http://www.di-mare.com/adolfo/cursos/2007-2/p2-ta-2.htm