La Matriz Abstracta no Polimorfica:
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Amigas 'defines'
test_rational.cpp
Ir a la documentación de este archivo.
00001 // test_rational.cpp (C) 2006 adolfo@di-mare.com
00002 
00003 /** \file  test_rational.cpp
00004     \brief Programa de prueba para la clase \c rational<INT>
00005 
00006     \author Adolfo Di Mare <adolfo@di-mare.com>
00007     \date   2007
00008 */
00009 
00010 #include "BUnit.h"
00011 #include <iostream>
00012 #include <climits> // INT_MAX
00013 
00014 using namespace std;
00015 
00016 // Escoja aquí cuál clase usa entre GranNum (Narvaja) y Number (Bosak)
00017 // #define Bosak
00018 // #define Narvaja
00019 #if defined(Bosak)
00020     #include "number.h"      // Clase de números de longitud arbitraria
00021     typedef  Number HugeInt; // sinónimo para la clase HugeInt
00022 #elif defined(Narvaja)
00023     #include "GranNum.h"     // Clase de números de longitud arbitraria
00024     typedef  BigNum HugeInt; // sinónimo para la clase HugeInt
00025 #else
00026     typedef  long   HugeInt; // sinónimo para la clase HugeInt
00027 #endif
00028 
00029 #include "rational.h"
00030 
00031 /// Prueba la clase \c rational<INT>.
00032 template <class INT>
00033 class test_rational : public TestCase {
00034 protected:
00035     rational<INT> m_half, m_quarter, m_one;
00036     rational<INT> m_half_neg, m_quarter_neg, m_one_neg;
00037     rational<INT> m_sep, m_sep_neg;
00038     bool m_super_lerdo; ///< Indica si hay que probar con numerotototes.
00039     bool m_super_numerotes; ///< Indica si se corren las pruebas que duran mucho.
00040 public:
00041     virtual void setUp(); ///< Establece el ambiente de prueba.
00042     /// Define si se corren o no las pruebas con super-numerotototes.
00043     void super_numerotes(bool sl = false) {
00044         m_super_numerotes = sl;
00045     }
00046     /// Define si se corren las pruebas que duran mucho.
00047     void super_lerdo(bool sl = false) {
00048         m_super_lerdo = sl;
00049         if (m_super_lerdo) {
00050             m_super_numerotes = true;
00051         }
00052     }
00053 public:
00054     bool run();
00055     void rat_tst(); void run_rest();
00056     void test_quiebra_Narvaja();
00057     void test_constructor();
00058     void test_destructor();
00059     void test_set();
00060     void test_op_equal();
00061     void test_num_den();
00062     void test_swap();
00063     void test_op_add_equal();
00064     void test_op_add();
00065     void test_op_mult_equal();
00066     void test_op_mult();
00067     void test_op_minus();
00068     void test_fromString();
00069     void test_op_comp();
00070     void test_op_in();
00071     void test_op_out();
00072     void test_simplify();
00073     void test_check_ok();
00074     void test_mcd();
00075     void test_op_cpp();
00076 }; // test_rational
00077 
00078 /// Método principal de la prueba.
00079 /// - Requiere que recién haya sido ejecutado \c setUp()
00080 template <class INT>
00081 bool test_rational<INT>::run() {
00082     test_quiebra_Narvaja();
00083     test_constructor();
00084     test_destructor();
00085     test_set();
00086     test_op_equal();
00087     test_num_den();
00088     test_swap();
00089     test_op_add_equal();
00090     test_op_add();
00091     test_op_mult_equal();
00092     test_op_mult();
00093     test_op_minus();
00094     test_fromString();
00095     test_op_comp();
00096     test_op_in();
00097     test_op_out();
00098 
00099     test_simplify();
00100     test_check_ok();
00101     test_mcd();
00102     test_op_cpp();
00103     rat_tst(); run_rest();
00104     return TestCase::wasSuccessful();
00105 }
00106 
00107 template <class INT>
00108 void test_rational<INT>::setUp() {
00109     m_half.set(1,2);
00110     m_quarter.set(1,4);
00111     m_one.set(1);
00112     m_half_neg.set(-1,2);
00113     m_quarter_neg.set(-1,4);
00114     m_one_neg.set(-1);
00115     m_sep.set(1,7);
00116     m_sep_neg.set(-1,7);
00117     m_super_lerdo = false;
00118     m_super_numerotes = false;
00119 }
00120 
00121 template <class INT> INT pow( const INT & r, int n );
00122 template <class INT> void grabador (ostream &COUT, const INT & r);
00123 template <class INT> const char * aHilera(const INT& r);
00124 template <class INT> const char * aHilera(const rational<INT>& r);
00125 template <class INT> rational<INT>& set( rational<INT>& r, const char * num, const char * den = "1" );
00126 template <class INT> INT& set( INT& num, const char * str );
00127 
00128 
00129 /// Datos de prueba que sirven para quebrar la implementación \c BigNum de Narvaja.
00130 template <class INT>
00131 void test_rational<INT>::test_quiebra_Narvaja() {
00132     {{  // test::quiebra_Narvaja()
00133         rational<INT> r;       assertTrue( r.num() ==  0 && r.den() == 1 );
00134         r.set(  5*11,  2*11 ); assertTrue( r.num() ==  5 && r.den() == 2 ); // Aquí Narvaja falla (1)
00135         rational<INT> s(-1,2); assertTrue( s.num() == -1 && s.den() == 2 ); // Aquí Narvaja falla (2)
00136         rational<INT> t(1,-2); assertTrue( t.num() == -1 && t.den() == 2 );
00137         assertTrue( r != s );
00138         assertTrue( s == t );                                               // Aquí Narvaja falla (3)
00139         std::basic_ostringstream<char> ost; // receptor de salida
00140         {
00141             const char* str = aHilera(r);
00142             ost.str(""); ost << str; assertTrue( ost.str() == "2" );        // Aquí Narvaja falla (4)
00143             delete [] str;
00144             ost.str("");
00145             str = aHilera(s.num());
00146             ost << '['<< str;
00147             delete [] str;
00148             str = aHilera( s.den() ); //  el denominador está malo.
00149             ost << '/' << str << ']';
00150             delete [] str; // retorna la memoria que aHilera() obtuvo
00151             assertTrue(  ost.str() == "[-1/2]" );                           // Aquí Narvaja falla (5)
00152             assertFalse( ost.str() == "[-1/0]" );                           // Aquí Narvaja falla (6)
00153         }
00154         if (1) {
00155             ost.str(""); ost << r;                    // Aquí Narvaja se encicla
00156             ost.str(""); ost << s;                    // Aquí Narvaja se encicla
00157             ost.str(""); ost << rational<INT>(-1,2);  // Aquí Narvaja se encicla
00158         }
00159     }}
00160     {   // Resto de las pruebas
00161     }
00162 }
00163 
00164 /// Datos de prueba para los constructores de la clase \c rational<INT>.
00165 template <class INT>
00166 void test_rational<INT>::test_constructor() {
00167     {{  // test::constructor()
00168         rational<INT> r,s,t(1,-2);
00169         assertTrue( r == rational<INT>(0) );
00170         assertTrue( s == rational<INT>(0,32) );
00171         assertTrue( t == rational<INT>(-100,200) );
00172         rational<INT> q = t;
00173         assertTrue( q == t );
00174     }}
00175     {   // Resto de las pruebas
00176     }
00177 }
00178 
00179 /// Datos de prueba para el destructor de la clase \c rational<INT>.
00180 template <class INT>
00181 void test_rational<INT>::test_destructor() {
00182     return test_constructor();
00183 }
00184 
00185 /// Datos de prueba para \c rational<INT>::set().
00186 template <class INT>
00187 void test_rational<INT>::test_set() {
00188     {{  // test::set()
00189         rational<INT> r;
00190         assertTrue( r == rational<INT>( 0 ) );
00191         r.set(-3, -4);
00192         assertTrue( r == rational<INT>( 3*11 , 4*11 ) );
00193     }}
00194     {   // Resto de las pruebas
00195     }
00196 }
00197 
00198 /// Datos de prueba para \c rational<INT>::num() y \c rational<INT>::den().
00199 template <class INT>
00200 void test_rational<INT>::test_num_den() {
00201     {{  // test::num_den()
00202         rational<INT> r;       assertTrue( r.num() ==  0 && r.den() == 1 );
00203         r.set( -1*13, -4*13 ); assertTrue( r.num() ==  1 && r.den() == 4 );
00204         r.set( -2*11,  5*11 ); assertTrue( r.num() == -2 && r.den() == 5 );
00205         r.set(  2*17, -6*17 ); assertTrue( r.num() == -1 && r.den() == 3 );
00206     }}
00207     {   // Resto de las pruebas
00208     }
00209 }
00210 
00211 /// Datos de prueba para \c rational<INT>::operator=().
00212 template <class INT>
00213 void test_rational<INT>::test_op_equal() {
00214     {{  // test::op_equal()
00215         rational<INT> r(1), s(18,56); assertTrue( r == rational<INT>(1) );
00216         r = s;                        assertTrue( r == ( r / ( r / s ) ) );
00217         r = 34;                       assertTrue( r == rational<INT>(34) );
00218         s = -3;                       assertTrue( s == rational<INT>(-3) );
00219     }}
00220     {   // Resto de las pruebas
00221     }
00222 }
00223 
00224 /// Datos de prueba para \c rational<INT>::swap().
00225 template <class INT>
00226 void test_rational<INT>::test_swap() {
00227     {{  // test::swap()
00228         rational<INT> r, s(18,56);  assertTrue( r == rational<INT>(0) );
00229         r.swap( s );                assertTrue( s == rational<INT>(0) );
00230         assertTrue( r == rational<INT>(18,56) );
00231     }}
00232     {   // Resto de las pruebas
00233     }
00234 }
00235 
00236 /// Datos de prueba para \c rational<INT>::operator +=() y \c rational<INT>::operator -=() .
00237 template <class INT>
00238 void test_rational<INT>::test_op_add_equal() {
00239     {{  // test::op_add_equal()
00240         rational<INT> add(0), sub(0);
00241         for ( int i=20; i>=-20; --i ) {
00242             add += rational<INT>(i-i, 20*i+1);
00243             sub -= rational<INT>(i-i, 20*i+1);
00244         }
00245         assertTrue( add == sub );
00246     }}
00247     {   // Resto de las pruebas
00248     }
00249 }
00250 
00251 /// Datos de prueba para \c rational<INT>::operator +() y \c rational<INT>::operator -() .
00252 template <class INT>
00253 void test_rational<INT>::test_op_add() {
00254     {{  // test::op_add()
00255         rational<INT> add(0), sub(0);
00256         for ( int i=20; i>=-20; --i ) {
00257             add = add + rational<INT>(i-i, 20*i+1);
00258             sub = sub - rational<INT>(i-i, 20*i+1);
00259         }
00260         assertTrue( add == sub );
00261     }}
00262     {   // Resto de las pruebas
00263     }
00264 }
00265 
00266 /// Datos de prueba para \c rational<INT>::operator *=() y \c rational<INT>::operator /=().
00267 template <class INT>
00268 void test_rational<INT>::test_op_mult_equal() {
00269     {{  // test::op_mult_equal()
00270         rational<INT> mlt(1), div(1);
00271         for ( int i=15; i>=-15; --i ) {
00272             mlt *= rational<INT>(17*i-1, 13*i+1);
00273             div /= rational<INT>(13*i+1, 17*i-1);
00274         }
00275         assertTrue( mlt == div );
00276     }}
00277     {   // Resto de las pruebas
00278     }
00279 }
00280 
00281 /// Datos de prueba para \c rational<INT>::operator *() y \c rational<INT>::operator /().
00282 template <class INT>
00283 void test_rational<INT>::test_op_mult() {
00284     {{  // test::op_mult()
00285         rational<INT> mlt(1), div(1);
00286         for ( int i=15; i>=-15; --i ) {
00287             mlt = mlt * rational<INT>(17*i-1, 13*i+1);
00288             div = div / rational<INT>(13*i+1, 17*i-1);
00289         }
00290         assertTrue( mlt == div );
00291     }}
00292     {   // Resto de las pruebas
00293     }
00294 }
00295 
00296 /// Datos de prueba para \c rational<INT>::operator -().
00297 template <class INT>
00298 void test_rational<INT>::test_op_minus() {
00299     {{  // test::op_minus()
00300         rational<INT> half_n(1,-2), quarter_n(-1,4);
00301         assertTrue( - half_n == rational<INT>(-1) * half_n );
00302         assertTrue( half_n * half_n == - quarter_n );
00303         assertTrue( half_n * half_n * half_n == - quarter_n * half_n );
00304     }}
00305     {   // Resto de las pruebas
00306     }
00307 }
00308 
00309 /// Datos de prueba para \c rational<INT>::test_fromString().
00310 template <class INT>
00311 void test_rational<INT>::test_fromString() {
00312     {{  // test::fromString()
00313         rational<INT> r, half(1,2), quarter(1,4);
00314         assertTrue( - half  == r.fromString(  "[---12/24]" ) );
00315         assertTrue( quarter == r.fromString( "[ -03/ -12 ]") );
00316         r.fromString( "[ -+-+-+-+- 4 / -- -+ -- 32  ]" );
00317         assertTrue( r == rational<INT>(1,8) );
00318     }}
00319     {   // Resto de las pruebas
00320     }
00321 }
00322 
00323 /// Datos de prueba para \c rational<INT>::test_simplify().
00324 template <class INT>
00325 void test_rational<INT>::test_simplify() {
00326     {{  // test::simplify()
00327         rational<INT> half(1,2);
00328         half.m_num *= 23;
00329         half.m_den *= 23;
00330         assertTrue( half != rational<INT>(23, 23*2) );
00331         half.simplify();
00332         assertTrue( half == rational<INT>(23, 23*2) );
00333     }}
00334     {   // Resto de las pruebas
00335     }
00336 }
00337 
00338 /// Datos de prueba para \c check_ok( const rational<INT>& ).
00339 template <class INT>
00340 void test_rational<INT>::test_check_ok() {
00341     {{  // test::check_ok()
00342         rational<INT> r, *nul=0;      assertFalse( check_ok(*nul) );
00343         r.m_num =  2;  r.m_den =  0;  assertFalse( check_ok(  r ) );
00344         r.m_num =  2;  r.m_den = -1;  assertFalse( check_ok(  r ) );
00345         r.m_num =  0;  r.m_den =  2;  assertFalse( check_ok(  r ) );
00346         r.m_num = 31;  r.m_den = 31;  assertFalse( check_ok(  r ) );
00347         r.simplify();                 assertTrue ( check_ok(  r ) );
00348     }}
00349     {   // Resto de las pruebas
00350     }
00351 }
00352 
00353 /// Datos de prueba para todos los operadores de comparación de \c rational<INT>.
00354 template <class INT>
00355 void test_rational<INT>::test_op_comp() {
00356     {{  // test::op_comp()
00357         rational<INT> neg_half(-1,2), quarter(1,4);
00358         assertTrue( neg_half == -(-neg_half) );
00359         assertTrue( neg_half <  quarter  );
00360         assertTrue( quarter  >  neg_half );
00361         assertTrue( neg_half <= quarter  );
00362         assertTrue( quarter  >= neg_half );
00363         assertTrue( neg_half != quarter  );
00364     }}
00365     {   // Resto de las pruebas
00366     }
00367 }
00368 
00369 /// Datos de prueba para \c operator<<().
00370 template <class INT>
00371 void test_rational<INT>::test_op_out() {
00372     {{  // test::op_out()
00373         std::basic_ostringstream<char> ost; // receptor de salida
00374         ost.str(""); ost << rational<INT>(-1,2);  assertTrue( ost.str() == "[-1/2]" );
00375         ost.str(""); ost << rational<INT>(-12);   assertTrue( ost.str() == "[-12]"  );
00376         ost.str(""); ost << rational<INT>(1-1,8); assertTrue( ost.str() == "[0]"    );
00377         ost.str(""); // Borra el receptor de salida
00378         ost << rational<INT>(-1,2) << rational<INT>(-12) << rational<INT>(1-1,8);
00379         assertTrue( ost.str() == "[-1/2][-12][0]" );
00380     }}
00381     {   // Esto también funciona pero es incómodo declarar 1a variable en cada caso
00382         std::basic_ostringstream<char> r_ost, s_ost, t_ost;
00383         r_ost << rational<INT>(-1,2);  assertTrue( r_ost.str() == "[-1/2]" );
00384         s_ost << rational<INT>(-12);   assertTrue( s_ost.str() == "[-12]"  );
00385         t_ost << rational<INT>(1-1,8); assertTrue( t_ost.str() == "[0]"    );
00386     }
00387     {   // Resto de las pruebas
00388     }
00389 }
00390 
00391 /// Datos de prueba para \c operator>>().
00392 template <class INT>
00393 void test_rational<INT>::test_op_in() {
00394     {{  // test::op_in()
00395         std::basic_istringstream<char> ist( "[-1/2] [-12] [0]" );
00396         rational<INT> r(0); ist >> r;  assertTrue( r == rational<INT>(-1,2) );
00397         rational<INT> s(1); ist >> s;  assertTrue( s == rational<INT>(-12)  );
00398         rational<INT> t(2); ist >> t;  assertTrue( t == rational<INT>(0)    );
00399 
00400         ist.str( "[ -+-+-+-+- 4 / -- -+ -- 32  ]" );
00401         rational<INT> u(3); ist >> u;  assertTrue( u == rational<INT>(1,8) );
00402     }}
00403     {   // Resto de las pruebas
00404     }
00405 }
00406 
00407 /// Datos de prueba para la función \c mcd().
00408 template <class INT>
00409 void test_rational<INT>::test_mcd() {
00410     {{  // test::mcd()
00411         assertTrue( 1 == mcd(1,2) );
00412         assertTrue( 2*3*5 == mcd( 2*2*2*2 * 3*3 * 5*5, 2*3*5 ) );
00413         assertTrue( 30 == mcd( -3600, -30 ) );
00414     }}
00415     {   // Resto de las pruebas
00416     }
00417 }
00418 
00419 /// Datos de prueba para los incrementadores \c c++ y \c --c.
00420 template <class INT>
00421 void test_rational<INT>::test_op_cpp() {
00422     {{  // test::op_cpp()
00423         rational<INT> r(3,2);
00424 
00425         assertTrue( r++ == rational<INT>(3,2) );
00426         assertTrue( r   == rational<INT>(5,2) );
00427 
00428         assertTrue( r-- == rational<INT>(5,2) );
00429         assertTrue( r   == rational<INT>(3,2) );
00430 
00431         assertTrue( --r == rational<INT>(1,2) );
00432     }}
00433     {   // Resto de las pruebas
00434         rational<INT> r(4,3);
00435 
00436         assertTrue( r++ == rational<INT>(4,3) );
00437         assertTrue( r   == rational<INT>(7,3) );
00438 
00439         assertTrue( r-- == rational<INT>(7,3) );
00440         assertTrue( r   == rational<INT>(4,3) );
00441 
00442         assertTrue( --r == rational<INT>(1,3) );
00443     }
00444     {   rational<INT> r(4,3);
00445 
00446         assertTrue( r-- == rational<INT>(4,3) );
00447         assertTrue( r   == rational<INT>(1,3) );
00448 
00449         assertTrue( r++ == rational<INT>(1,3) );
00450         assertTrue( r   == rational<INT>(4,3) );
00451 
00452         assertTrue( --r == rational<INT>(1,3) );
00453     }
00454 }
00455 
00456 /// Antiguo programa de prueba para la clase \c rational<INT>.
00457 template <class INT>
00458 void test_rational<INT>::rat_tst() {
00459     rational<INT> r,       // r.rational<INT>();
00460            s(1),    // s.rational<INT>(1);
00461            t = 1,   // t.rational<INT>(1);
00462            u(1,2);  // u.rational<INT>(1,2);
00463 
00464     assertTrue( r == rational<INT>(0) );
00465     assertTrue( s == rational<INT>(1) );
00466     assertTrue( t == s );
00467     assertTrue( u == rational<INT>(1,2) );
00468 
00469     rational<INT>      a = t;
00470     assertTrue( a == t );
00471                a = t;
00472     assertTrue( a == t );
00473 
00474     (a += s * rational<INT>(2)) += rational<INT>(4);
00475     assertTrue( a == rational<INT>(7) );
00476     assertTrue( s == rational<INT>(1) );
00477     assertTrue( rational<INT>(1) == s );
00478 
00479     a = rational<INT>(4, -5);
00480     rational<INT> b(-10, 6);
00481     a *= b;
00482 
00483     assertTrue( a == rational<INT>( 4*-10,-5*6) );
00484 
00485     a=b;
00486     assertTrue( a == b );
00487     assertTrue( b == a );
00488 
00489     a = rational<INT>(4, -5);
00490     a += b;
00491     assertTrue( a == rational<INT>( 4*6 + -5*-10, -5*6 ) );
00492 
00493     a -= b;
00494     assertTrue( a == rational<INT>(-4, 5) );
00495 
00496     a = b;
00497     assertTrue( a == b );
00498 
00499     a -= a;
00500     assertTrue( a == rational<INT>(0) );
00501     assertTrue( rational<INT>(0) == a );
00502 
00503     rational<INT> c(15);
00504     assertTrue( rational<INT>(15) == c );
00505 
00506     a /= c;
00507     assertTrue( a == rational<INT>(0) );
00508     assertTrue( rational<INT>(0) == a );
00509 
00510     a = 1234567l;
00511     assertTrue( a == rational<INT>(1234567l) );
00512 
00513     long d = 4;
00514     a = d;
00515     assertTrue( a == rational<INT>(d) );
00516     assertTrue( rational<INT>(d) == a );
00517 
00518     a += (b = rational<INT>(5));
00519     assertTrue( a == rational<INT>(d+5) );
00520     assertTrue( b == rational<INT>(5) );
00521 
00522     a = rational<INT> (4, -5);
00523     b = rational<INT> (5, -4);
00524     assertTrue( a*b == rational<INT>(1) );
00525     assertTrue( a/b == rational<INT>( -4*4 , -5*5 ) );
00526     assertTrue( b/a == rational<INT>( -5*5 , -4*4 ) );
00527 
00528     rational<INT> tot = rational<INT>(0);
00529     for (int i = 0; i <= 50; ++i) {
00530         tot += rational<INT>(i, i+1);
00531     }
00532     {
00533         bool good_sum = false;
00534         good_sum = good_sum || TestCase::toString(tot) == "[2668385009430893323/8818708306321991968]";
00535         good_sum = good_sum || TestCase::toString(tot) == "[64263385/206760032]";
00536         good_sum = good_sum || TestCase::toString(tot) == "[3067/4896]";
00537         assertTrue_Msg( "sum(0==>50 { rational<INT>(i, i+1) }", good_sum );
00538     }
00539 
00540     assertTrue( rational<INT>( 1,4) == rational<INT>().fromString("[ 1 / - - 4 ]"));
00541     assertTrue( rational<INT>(-1,4) == rational<INT>().fromString("[-1 / - - 4 ]"));
00542     assertTrue( rational<INT>(-1,4) == rational<INT>().fromString("[ - 1 / -- 4 ]"));
00543     assertTrue( rational<INT>( 1,4) == rational<INT>().fromString("[ - 1 / -  4 ]"));
00544 
00545     {   // selection_sort()
00546 
00547         rational<INT> VEC[17];
00548         size_t  nVEC = sizeof(VEC) / sizeof(*VEC);
00549 
00550         size_t i;
00551         srand( 1492 );
00552         for (i=0; i<nVEC; ++i) {
00553             rational<INT> r(rand(), rand());
00554             VEC[i] = r;
00555             assertTrue( check_ok( VEC[i] ) );
00556             assertTrue( r == VEC[i] );
00557         }
00558 
00559         selection_sort(VEC, nVEC);
00560         assertTrue( Ordenado(VEC, nVEC) );
00561     }
00562 }
00563 
00564 /// Retorna un racional construido a partir de los valores almacenados en \c num y \c den.
00565 /// - Los valores negativos comienzan con el caracter \c '-' al principio de la hilera.
00566 template <class INT>
00567 rational<INT> rat( const char* num , const char * den = "1" ) {
00568     rational<INT> RES;
00569     return set( RES, num, den );
00570 }
00571 
00572 /// Método complementario de prueba.
00573 /// - Esto lo ejecita \c run().
00574 template <class INT>
00575 void test_rational<INT>::run_rest() {
00576     {   //  A54641.cpp
00577         assertTrue(  rational<INT>(0) * rational<INT>(0,2) == rational<INT>(0,4) );
00578 
00579         assertTrue( rat<INT>( "100" , "2" ) * rat<INT>( "2" , "100" ) == rat<INT>( "1" , "1" ) );
00580         assertTrue( rat<INT>( "99" , "99" ) * rat<INT>( "99" , "99" ) == rat<INT>( "1" ) );
00581 
00582         assertTrue( m_half / rat<INT>( "1" , "1" ) == rat<INT>( "128" , "256" ) );
00583         assertTrue( rat<INT>( "10" , "40" )/rat<INT>( "10" , "40" )  == rat<INT>( "1" ) );
00584 
00585         assertTrue( m_quarter / rat<INT>( "2" )  == rat<INT>( "1" , "8" ) );
00586         assertTrue( m_quarter / m_half == rat<INT>( "2" , "4" ) );
00587 
00588         assertTrue( rat<INT>( "75" , "100" ) / rat<INT>( "100" , "75" ) == rat<INT>( "75" , "100" ) * rat<INT>( "75" , "100" ));
00589 
00590         assertTrue( ( m_half + m_quarter ) == rat<INT>( "3" , "4" ) );
00591 
00592         assertTrue( ( m_one + m_quarter ) == rat<INT>( "5" , "4" ) );
00593         assertTrue( ( rat<INT>( "75" , "100" )+= rat<INT>( "0" ) )== rat<INT>( "75" , "100" )  );
00594 
00595         assertTrue( ( m_half + m_quarter) == rational<INT>(3,4) );
00596         assertTrue( ( m_half + rational<INT>(85,40000)) == rational<INT>(40170,80000) );
00597 
00598         assertTrue(  (m_one + m_quarter) == rational<INT>(5,4) );
00599         assertTrue(  (rational<INT>(75,100)+= rational<INT>(0) )== rational<INT>(75,100)  );
00600 
00601         assertTrue(   (m_quarter + rational<INT>(-1)) ==  rational<INT>(-3,4) );
00602         assertTrue(   (rational<INT>(50,37)+rational<INT>(50,37) ) == rational<INT>(2)*rational<INT>(50,37) );
00603 
00604         assertTrue((  m_half - m_quarter )== m_quarter );
00605         assertTrue((  rational<INT>(10,40) - rational<INT>(10,40) ) == rational<INT>(0) );
00606 
00607         assertTrue( ( -m_half + m_quarter)== rational<INT>(-1,4) );
00608         assertTrue( ( rational<INT>(-75,100) )== m_quarter-m_one  );
00609 
00610         assertTrue( ( rational<INT>(75,100) - rational<INT>(75)) == -rational<INT>(7425,100) );
00611         assertTrue( ( m_quarter - rational<INT>(1) )== rational<INT>(-3,4) );
00612 
00613         assertTrue(  m_half * rational<INT>(0,2) == rational<INT>(0,4) );
00614         assertTrue(  m_half * rational<INT>(0,2) == rational<INT>(0) );
00615 
00616         assertTrue(  rational<INT>(0) * rational<INT>(0,2) == rational<INT>(0,4) );
00617         assertEquals( rat<INT>("1", "1") ,  m_one );
00618         assertEquals( rat<INT>("1", "2") ,  m_half );
00619         assertEquals( rat<INT>("1", "4") ,  m_quarter );
00620         assertTrue(  m_half / rational<INT>(1,1) == rational<INT>(13,26) );
00621         assertTrue(  rational<INT>(10,40)/rational<INT>(10,40)  == rational<INT>(1) );
00622 
00623         assertTrue(  m_quarter / rational<INT>(2)  == rational<INT>(1,8) );
00624         assertTrue(  m_quarter / m_half == rational<INT>(2,4));
00625 
00626         assertTrue( (rational<INT>(75,100) /= rational<INT>(100,75)) == rational<INT>(75*75,100*100) );
00627 
00628         assertTrue(   (rational<INT>(50,37)+=rational<INT>(50,37) ) == rational<INT>(2)*rational<INT>(50,37) );
00629 
00630         assertTrue((  rational<INT>(10,40) -= rational<INT>(10,40) ) == rational<INT>(0) );
00631 
00632         assertTrue( ( rational<INT>(-3,4) -= m_quarter   )== rational<INT>(-1) );
00633         assertTrue( ( -m_half + m_quarter)== rational<INT>(-1,4) );
00634 
00635         assertTrue( ( rational<INT>(75,100) -= rational<INT>(75)) ==  rational<INT>(75*1-75*100, 1*100) );
00636 
00637         assertTrue(  (rational<INT>(99,99) *= rational<INT>(0,2)) == rational<INT>(0,4) );
00638 
00639         assertTrue(  (rational<INT>(100,2) *= rational<INT>(2,100)) == rational<INT>(1,1) );
00640         assertTrue(  (rational<INT>(99,99) *= rational<INT>(99,99)) == rational<INT>(1) );
00641         assertTrue(  (rational<INT>(10,40) /= rational<INT>(10,40))  == rational<INT>(1) );
00642 
00643         assertTrue( (rational<INT>(75,100) *= rational<INT>(100,75)) == rational<INT>(75,75) );
00644 
00645         assertTrue(  m_quarter < m_half );
00646         assertTrue(  rational<INT>(-10,40)  < rational<INT>(10,40) );
00647 
00648         assertFalse(  m_quarter   < m_quarter );
00649         assertFalse(  rational<INT>(4) < rational<INT>(40,10)  );
00650 
00651         assertFalse( rational<INT>(20,40) < rational<INT>(40,80) );
00652         assertFalse(   rational<INT>(0,100) < rational<INT>(0) );
00653 
00654         assertFalse( ( m_half-m_quarter ) != rational<INT>(10,40) );
00655         assertFalse(  rational<INT>(10,40)  != m_quarter );
00656 
00657         assertFalse(  m_one-m_quarter   != rational<INT>(75,100) );
00658         assertFalse(  rational<INT>(-75,100) != (m_quarter-m_one ) );
00659 
00660         assertTrue(  rational<INT>(75,100) !=  (m_quarter-m_one) );
00661         assertFalse(  rational<INT>(0,100) != rational<INT>(0) );
00662 
00663         assertTrue(  m_quarter <= m_half );
00664         assertTrue(  rational<INT>(-10,40)  <= rational<INT>(10,40) );
00665 
00666         assertTrue(  m_quarter   <= m_quarter );
00667         assertTrue(  rational<INT>(4) <= rational<INT>(40,10)  );
00668         assertTrue( rational<INT>(20,40) <= rational<INT>(40,80) );
00669         assertTrue(   rational<INT>(0,100) <= rational<INT>(0) );
00670         assertTrue(  m_quarter >= m_quarter  );
00671         assertTrue(  rational<INT>(10,40)  >= -rational<INT>(10,40) );
00672 
00673         assertTrue(  m_one >= m_quarter );
00674         assertTrue(  rational<INT>(-75,100) >= m_quarter-m_one  );
00675 
00676         assertTrue( rational<INT>(79,57) >=  rational<INT>(75,150) );
00677         assertTrue( rational<INT>(125,100) >= m_one+m_quarter );
00678 
00679         assertTrue(  m_quarter >= m_quarter  );
00680         assertTrue(  rational<INT>(10,40)  >= -rational<INT>(10,40) );
00681 
00682         assertTrue(  m_one >= m_quarter );
00683         assertTrue(  rational<INT>(-75,100) >= m_quarter-m_one  );
00684 
00685         assertTrue( rational<INT>(79,57) >=  rational<INT>(75,150) );
00686         assertTrue( ( rational<INT>(10,40) = m_one) == m_one );
00687         assertTrue( rational<INT>(-75,100) == (m_quarter-m_one ) );
00688 
00689         assertEquals( rat<INT>("1", "1") ,  m_one );
00690         assertEquals( rat<INT>("1", "2") ,  m_half );
00691         assertEquals( rat<INT>("1", "4") ,  m_quarter );
00692     }
00693 
00694     {   // A33984
00695         rational<INT> m_five_neg(-5), m_half_neg(1,-2), m_cero(0);
00696         rational<INT> m_quarter_neg(-1,4), m_one_neg(-1);
00697         //1) Suma de dos numeros racionales positivos  con simplificacion
00698         assertTrue(m_half + m_quarter == rational<INT>(30,40) );
00699         assertTrue(rational<INT>(30,40) == m_quarter + m_half );
00700         //2) Suma de entero positivo  + racional positivo con simplificacion
00701         assertTrue(m_one + m_quarter == rational<INT>(125,100) );
00702         //3) Suma de racional positivo + entero positivo
00703         assertTrue(rational<INT>(125,100) == m_quarter+m_one );
00704         //4) Suma de entero negativo con racional positivo
00705         assertTrue(m_five_neg + m_half == rational<INT>(-9,2) );
00706         //5)Suma de racional positivo + entero negativo
00707         assertTrue(rational<INT>(-9,2)== m_half+m_five_neg);
00708         //6) Suma de entero negativo con racional negativo con simplificacion
00709         assertTrue(m_five_neg + m_quarter_neg == rational<INT>(-21,4) );
00710         //7) Suma de racional negativo + entero negativo
00711         assertTrue(rational<INT>(-20,16) == m_quarter_neg + m_one_neg);
00712         //8) Suma de entero positivo con racional negativo
00713         assertTrue(m_one + m_quarter_neg == rational<INT>(3,4));
00714         //9) Suma de racional negativo + entero positivo
00715         assertTrue(rational<INT>(3,4) == m_quarter_neg + m_one);
00716         //10) Suma de racionales negativos
00717         assertTrue(m_half_neg + m_quarter_neg == rational<INT>(-3,4));
00718         assertTrue(rational<INT>(-3,4) == m_quarter_neg+m_half_neg);
00719         //11) Suma de enteros negativos con simplicacion
00720         assertTrue(m_one_neg + m_five_neg == rational<INT>(-30,5));
00721         assertTrue(rational<INT>(-30,5) == m_five_neg + m_one_neg);
00722         //12)Suma de racional positivo + cero
00723         assertTrue(m_half + m_cero == rational<INT>(1,2));
00724         assertTrue(rational<INT>(1,2) == m_cero + m_half);
00725         //13)Suma de racional negativo + cero
00726         assertTrue(m_half_neg + m_cero == rational<INT>(-1,2));
00727         //14)Suma de cero + racional negativo
00728         assertTrue(rational<INT>(-1,2) == m_cero + m_half_neg);
00729         //15)Suma de entero positivo + cero
00730         assertTrue(m_one+ m_cero == rational<INT>(1));
00731         //16)Suma de cero + entero positivo
00732         assertTrue(rational<INT>(1) == m_cero + m_one);
00733         //17)Suma de entero negativo + cero
00734         assertTrue(-m_one+ m_cero == rational<INT>(-1));
00735         //18)Suma de cero + entero negativo
00736         assertTrue(rational<INT>(-1) == m_cero + m_one_neg);
00737         //19)Suma de ceros
00738         assertTrue(m_cero+ m_cero == rational<INT>(0));
00739         assertTrue(rational<INT>(0) == m_cero+ m_cero);
00740         //20)Suma de INT_MAX + cero
00741         assertTrue(rational<INT>(INT_MAX) + m_cero == rational<INT>(INT_MAX));
00742         //21)Suma de cero + INT_MAX
00743         assertTrue(rational<INT>(INT_MAX) ==m_cero + rational<INT>(INT_MAX));
00744         //22)Suma de - INT_MAX + cero
00745         assertTrue(rational<INT>(-INT_MAX) + m_cero == rational<INT>(-INT_MAX));
00746         //23)Suma de cero +- INT_MAX
00747         assertTrue(rational<INT>(-INT_MAX) == m_cero + rational<INT>(-INT_MAX));
00748         //24)Suma de dos racionales que de cero
00749         assertTrue(m_half_neg + m_half == rational<INT>(0));
00750         assertTrue(rational<INT>(0) == m_half + m_half_neg);
00751         //25)Suma de dos enteros que de cero
00752         assertTrue(m_one + m_one_neg == rational<INT>(0));
00753         assertTrue(rational<INT>(0) == m_one_neg+ m_one);
00754         //26)Suma de rational<INT>(INT_MAX,INT_MAX) + rational<INT>(INT_MAX,INT_MAX)
00755         assertTrue(rational<INT>(INT_MAX,INT_MAX) + rational<INT>(INT_MAX,INT_MAX) == rational<INT>(2));
00756         //27)Suma de rational<INT>(INT_MAX,INT_MAX) + rational<INT>(-INT_MAX,INT_MAX)
00757         assertTrue(rational<INT>(INT_MAX,INT_MAX) + rational<INT>(-INT_MAX,INT_MAX) == rational<INT>(0));
00758         //28)Suma cero + cero
00759         assertTrue(m_cero + m_cero == rational<INT>(0));
00760 
00761         assertEquals( rat<INT>("1", "1") ,  m_one );
00762         assertEquals( rat<INT>("1", "2") ,  m_half );
00763         assertEquals( m_one_neg ,  - m_one );
00764         assertEquals( m_half_neg , - m_half );
00765         assertEquals( - m_one_neg ,  m_one );
00766         assertEquals( - m_half_neg , m_half );
00767         assertTrue( m_one_neg ==  - m_one );
00768         assertTrue( m_half_neg == - m_half );
00769         assertTrue( - m_one_neg ==  m_one );
00770         assertTrue( - m_half_neg == m_half );
00771         assertTrue( m_one_neg ==  rational<INT>(-1) );
00772         assertTrue( m_half_neg == rational<INT>(-1,2) );
00773 
00774         assertTrue( m_half_neg + m_half == rational<INT>(0) );
00775         assertTrue( rational<INT>(0) == m_one_neg + m_one );
00776 
00777         assertTrue( (m_half_neg + m_half) == rational<INT>(0));
00778         assertTrue(  rational<INT>(0) == (m_one_neg + m_one) );
00779         assertTrue(  rat<INT>("0") == (m_one_neg + m_one) );
00780         assertEquals( (m_half_neg + m_half) , rational<INT>(0));
00781         assertEquals(  rational<INT>(0) , (m_one_neg + m_one) );
00782     }
00783 
00784     {   // datos de prueba viejos
00785         assertTrue( m_half+m_quarter == rational<INT>(30,40) );
00786         assertTrue( rational<INT>(30,40) == m_quarter+m_half );
00787 
00788         assertTrue( m_one+m_quarter == rational<INT>(125,100) );
00789         assertTrue( rational<INT>(125,100) == m_quarter+m_one );
00790 
00791         assertTrue(  rational<INT>(1,3) != rational<INT>(33,100)  );
00792 
00793         assertTrue(  m_half-m_quarter == rational<INT>(10,40) );
00794         assertTrue(  rational<INT>(10,40)  == -m_quarter+m_half );
00795 
00796         assertTrue(  m_one-m_quarter   == rational<INT>(75,100) );
00797         assertTrue(  rational<INT>(-75,100) == m_quarter-m_one  );
00798 
00799         assertEquals( rational<INT>(-75,100) ,  m_quarter-m_one );
00800         assertTrue(   rational<INT>(125,100) == m_one+m_quarter );
00801 
00802         assertTrue(  m_half * m_quarter == rational<INT>(125,1000) );
00803         assertTrue(  rational<INT>(125,1000)  == m_quarter * m_half );
00804 
00805         assertTrue(  m_one * m_quarter   == rational<INT>(10,40) );
00806         assertTrue(  rational<INT>(10,40) == m_quarter *  m_one  );
00807 
00808         assertTrue(  rational<INT>(25,100) == m_one * m_quarter );
00809 
00810         assertTrue(  m_half / m_quarter == rational<INT>(100,50) );
00811         assertTrue(  rational<INT>(50,100)  == m_quarter / m_half );
00812 
00813         assertTrue(  m_one / m_quarter   == rational<INT>(40,10) );
00814         assertTrue(  rational<INT>(10,40) == m_quarter /  m_one  );
00815 
00816         assertTrue(  rational<INT>(100, 100) == m_half / m_half );
00817     }
00818 
00819     if (m_super_lerdo) {   // 2^1024 * 3 ^ 512;
00820         INT deDOS=1, deTRES=1;
00821         for (int i=1; i<=1024; ++i ) {
00822             INT elOTRO = (2 * deDOS);
00823             assertTrue( deDOS < elOTRO );
00824             deDOS = elOTRO;
00825         }
00826         for (int i=1; i<=512; ++i ) {
00827             deTRES *= 3;
00828         }
00829         assertTrue( mcd<INT>(deDOS, deTRES) == 1 );
00830     }
00831 
00832     if (m_super_lerdo) {   // Progresión geométrica
00833         int n = 1024;  //         1         2        3          4
00834         INT r; set( r , "1234567890123456789012345678901234567890" );
00835         INT a; set( a , "9876543210987654321098765432109876543210" );
00836 
00837         INT SUMA = 0;
00838         INT u = a;
00839         for ( int i=0; i<n; ++i ) {
00840             SUMA += u;
00841             u *= r;
00842         }
00843         assertTrue( SUMA == a * ( pow(r,n) - 1 ) / ( r-1 ) );
00844     }
00845 
00846     if (m_super_numerotes) {
00847         rational<INT> r,s,t;
00848         set(r, "10000000000000000", "4" );
00849         set(s, "100000000", "2" );
00850         set(t, "100000000", "2" );
00851         assertTrue( r == s * t );
00852         assertTrue( s * t == r );
00853     }
00854 
00855     if (m_super_numerotes) {   //  A54641.cpp
00856         assertTrue( rat<INT>("10000000000000000", "4" ) == rat<INT>("100000000", "2" ) * rat<INT>("100000000", "2" ) );
00857         assertTrue( rat<INT>( "900" , "2" ) * rat<INT>( "100000000000" ) == rat<INT>( "90000000000000" , "2" ) );
00858         assertTrue( rat<INT>( "1" , "1000000" )/rat<INT>( "1000000" , "1" ) == rat<INT>( "1" , "1000000" )*rat<INT>( "1" , "1000000" ) );
00859         assertTrue(  (rat<INT>("900","2")  *= rat<INT>("100000000000")) == rat<INT>("90000000000000","2") );
00860         assertTrue( (rat<INT>("1","1000000") /= rat<INT>("1000000","1")) ==  rat<INT>("1","1000000000000") );
00861         assertTrue( - rat<INT>("8000000000000000") == ( rational<INT>() - rat<INT>("8000000000000000") ) );
00862         assertTrue( rational<INT>(20,100) == rat<INT>("20000000000","100000000000") );
00863         assertTrue( ( rat<INT>( "1" , "2" ) + rat<INT>( "85" , "40000" ) ) == rat<INT>( "40170" , "80000" ) );
00864         assertTrue( ( m_half + rat<INT>( "85" , "40000" ) ) == rat<INT>( "40170" , "80000" ) );
00865     }
00866 
00867     // assertTrue(  rational<INT>(100, 100) != m_half / m_half );
00868     // assertFalse( rational<INT>(100, 100) == m_half / m_half );
00869 }
00870 
00871 #ifdef __GNU__
00872     #define NO_long_long
00873 #endif
00874 
00875 /// Programa principal [viejo] desde donse se invocan todas las pruebas
00876 int main_viejo() {
00877     #ifdef NO_long_long
00878         if (1) { // código para ver si aHilera() funciona
00879             const char * n = aHilera<long long>(  12345678900 );
00880             const char * m = aHilera<long long>( 987654321001 );
00881             const char * p = aHilera<long long>(  -8765432100 );
00882             cout << n << endl;
00883             cout << m << endl;
00884             cout << p << endl;
00885             delete [] n;
00886             delete [] m;
00887             delete [] p;
00888         }
00889         if (1) { // código para ver si grabador() funciona
00890             long long
00891                 n =  12345678900,
00892                 m = 987654321001,
00893                 p =  -8765432100;
00894             grabador( cout , n ); cout << endl;
00895             grabador( cout , m ); cout << endl;
00896             grabador( cout , p ); cout << endl;
00897         }
00898     #endif
00899 
00900     if (1) { // código para ver si aHilera( rational<INT> ) funciona
00901         rational<HugeInt> r(-12,5);
00902         const char * c = aHilera( r );
00903         cout << r << " ==> " << c << endl;
00904         delete [] c;
00905     }
00906     if (1) { // código para ver que "cout <<" funciona
00907         rational<HugeInt>
00908             n_five ( 5 ),
00909             n_five_neg ( -5 ),
00910             n_half_neg(1,-2),
00911             n_cero ( 0 ),
00912             n_quarter_neg(-1,4),
00913             n_one_neg ( -1 );
00914         cout << n_cero << endl;
00915         cout << n_five << endl;
00916         cout << n_quarter_neg << endl;
00917         cout << n_one_neg << endl;
00918         cout << n_half_neg << endl;
00919         cout << n_five_neg << endl;
00920     }
00921     return 0;
00922 }
00923 
00924 #include <cstdio> // isdigit()
00925 
00926 /// Toma los dígitos de \c str y los asigna como valor de \c num.
00927 /// - Solo incluye los números que están al principio de la hilera \c str.
00928 /// - Los valores negativos comienzan con el caracter \c '-' al principio de la hilera.
00929 /// - Retorna \c num.
00930 template <class INT>
00931 INT& set( INT& num, const char * str ) {
00932     num = INT(0);
00933     if ( str==0 ) {
00934         return num;
00935     }
00936     bool neg; // indica que el  número es negativo
00937     if ( *str == '-') {
00938         neg = true;
00939         str++;
00940     }
00941     else  {
00942         neg = false;
00943     }
00944     INT DIEZ = INT(10);
00945     while ( isdigit(*str) ) {
00946         num *= DIEZ;
00947         num += INT( (*str) - '0' );
00948         str++;
00949     }
00950     if (neg) {
00951         num = -num;
00952     }
00953     return num;
00954 }
00955 
00956 
00957 /// Toma los dígitos de \c num y \c den y los asigna como valor de \c r.
00958 /// - Solo incluye los números que están al principio de las hileras.
00959 /// - Los valores negativos comienzan con el caracter \c '-' al principio de la hilera.
00960 /// - Retorna \c r.
00961 template <class INT>
00962 rational<INT>& set( rational<INT>& r, const char * num, const char * den ) {
00963     INT NUM, DEN;
00964     set( NUM, num );
00965     set( DEN, den );
00966     r.set( NUM, DEN );
00967     return r;
00968 }
00969 
00970 /// Calcula y retorna el residuo \c ( n % m ).
00971 template <class INT>
00972 inline INT operator% ( const INT& n , const INT& m ) {
00973     INT temp = n/m;
00974     return INT( n - temp * m );
00975 /*  Nota:
00976     Supongamos que ya tenemos un algoritmo op/(n,m) que calcula la
00977     división entera (n/m). A partir de ese algoritmo de división se
00978     puede calcular el residuo usando una multiplicación y una resta.
00979 
00980     El valor que el algoritmo de la división d==(n/m) tiene la
00981     siguiente propiedad:
00982     - n == d*m + r, en donde 0 <= r < m.
00983 
00984     A partir de esta ecuación se puede hacerla siguiente deducción:
00985     n == d*m + r             <==>
00986     d*m + r == n             <==>
00987     r == n - (d*m)           <==>  d == op/( n , m )
00988     r == n - (op/(n,m) * m)
00989 
00990     O sea que es posible calcular el residuo usando la fórmula
00991     (n - (op/(n/m) * m)
00992 */
00993 }
00994 
00995 /// Especialización para que aHilera<INT>() funcione con racionales.
00996 template <class INT>
00997 const char * aHilera(const rational<INT>& r) {
00998     INT temp = r.num() / r.den();
00999     return aHilera(temp);
01000     /*  Nota
01001         Como "r" es un número racional, no es posible "sacarle" los
01002         dígitos usando el truco del módulo diez:
01003             digito = numero % 10; // último "digito" de "numero"
01004         Cada vez que se usa la división, la clase rational<> produce un
01005         valor quebrado que nunca llegará a sercero, por lo que algoritmo
01006         aHilera( rational<INT> ) nunca retorna si se le usa con un
01007         argumento racional.
01008         - Por eso hace falta esta especialización de la plantilla.
01009     */
01010 }
01011 
01012 /// Construye una hilera que tiene el valor de \c r en dígitos decimales.
01013 /// - Al terminar de usar la hilera, es responsabilidad del programador
01014 ///   usuario retornar la memoria de la hilera retornada.
01015 /// \pre \c INT debe ser una clase entera (no puede ser \c rational<INT>).
01016 template <class INT>
01017 const char * aHilera(const INT& r) {
01018     int signo = 0; // cantidad de campos para almacenar el signo: { 0 , 1 }
01019     if ( r == INT(0) ) {
01020         char * res = new char[2];
01021         res[0] = '0';
01022         res[1] =  0 ;
01023         return res;
01024     }
01025     else if ( r<INT(0) ) {
01026         signo = 1; // el '-' ocupa un campo en la hilera de retorno
01027     }
01028     INT DIEZ = 10, digito;
01029     INT tmp = ( signo==0 ? r : 0-r );
01030     int n=0;  // cantidad de dígitos de "r"
01031     while ( tmp != INT(0) ) {
01032         tmp /= DIEZ;
01033         ++n;
01034     }
01035     char * res = new char[n+1+signo];
01036     res[n+signo] = 0;
01037     if (signo == 1) {
01038         res[0] = '-';
01039         ++res; // se "brinca" el signo
01040         tmp = 0-r;
01041     }
01042     else {
01043         tmp = r;
01044     }
01045     while ( n>0 ) {
01046         digito = tmp % DIEZ;
01047         tmp /= DIEZ;
01048         --n;
01049         for ( int j=0; j<10; ++j ) { // no usa el convertidor <INT> ==> <int>
01050             if ( digito == INT(j) ) {
01051                 res[n] = char('0'+j); // encuentra cuál dígito escoger
01052                 break;
01053             }
01054         }
01055     }
01056     if (signo == 1) {
01057         --res; // se "des-brinca" el signo
01058     }
01059     return res;
01060 }
01061 
01062 /// Graba el valor de \c "n" en el flujo \c "COUT".
01063 template <class INT>
01064 void grabador (ostream &COUT, const INT & r) {
01065     if ( r < INT(0) ) {
01066         COUT << "-";
01067         grabador( COUT , -r );
01068         return;
01069     }
01070     else if ( r == INT(0) ) {
01071         COUT << "0";
01072         return;
01073     }
01074     INT DIEZ = 10;
01075     INT tmp = r;
01076     INT digito, vuelto = 0;
01077     int n=0;
01078     while ( tmp != INT(0) ) {
01079         digito = tmp % DIEZ; // en "vuelto" quedan los dígitos
01080         tmp /= DIEZ;         // de "tmp" en orden inverso
01081         vuelto *= DIEZ;
01082         vuelto += digito;
01083         ++n;
01084     }
01085     for ( int i=0; i<n; ++i ) {
01086         digito = vuelto % DIEZ;
01087         vuelto /= DIEZ;
01088         for ( int j=0; j<10; ++j ) {
01089             if ( digito == INT(j) ) {     // encuentra cuál dígito escoger
01090                 COUT << char('0'+j);
01091                 break;
01092             }
01093         }
01094     }
01095     // este algoritmo funciona con cualquier valor entero
01096 }
01097 
01098 /// Calcula y retorna <code> r^n == r * ... * r  </code> (\c n veces).
01099 template <class INT>
01100 INT pow( const INT & r, int n ) {
01101     INT res = 1;
01102     for ( int i=0; i<n; ++i ) {
01103         res *= r;
01104     }
01105     return res;
01106 }
01107 
01108 /// Método de ordenamiento de selección.
01109 /// - Deja el arregle \c A[] ordenado.
01110 /// - Trabaja en el rango \c [0..n-1].
01111 template <class T>
01112 void selection_sort( T* A, size_t n) {
01113     for ( size_t i=0, m=n-1; i<m; ++i ) {
01114         size_t idx = i;
01115         T      min = A[idx];
01116         for (size_t j=i+1; j<n; ++j) {
01117             /* compare each key with current min */
01118             if (A[j] < min) {
01119                 idx = j;
01120                 min = A[idx];
01121             }
01122         }
01123         T tmp  = A[i];   // Intercambia(A[i], A[idx])
01124         A[i]   = A[idx];
01125         A[idx] = tmp;
01126     }
01127 }
01128 /// Retorna "true" cuando el vector está ordenado ascendentemente.
01129 /// - Revisa desde \c A[0] hasta \c A[N-1].
01130 template <class T>
01131 bool Ordenado (T* A, size_t n) {
01132     for (size_t i = 0; i < n-1; ++i) {
01133         if (A[i] > A[i+1]) {
01134             return false;
01135         }
01136     }
01137     return true;
01138 } // Ordenado()
01139 
01140 #undef TEST_BIG_NUM
01141 
01142 #if defined(_INCLUDED_NUMBER_H) && defined(USE_SMART_PTR)
01143     // Clase Number Krzysztof Bosak
01144     #define TEST_BIG_NUM
01145 #endif
01146 
01147 #if defined(GranNum_h) && defined(FALSE)
01148     // Clase BigNum de Guillermo Narvaja
01149     #define TEST_BIG_NUM
01150 #endif
01151 
01152 #ifdef TEST_BIG_NUM
01153 #endif
01154 
01155 /// Programa principal desde donse se invocan todas las pruebas
01156 int main() {
01157     if (1) {
01158         test_rational<HugeInt>  test_rational_Instance;
01159         test_rational_Instance.setUp();
01160         test_rational_Instance.super_lerdo(false);
01161         test_rational_Instance.run();
01162         cout << test_rational_Instance.report() << endl;
01163     //  cout << test_rational_Instance.toXML();
01164     }
01165     if (1) {
01166         test_rational<long long>  test_rational_Instance;
01167         test_rational_Instance.setUp();
01168         test_rational_Instance.run();
01169         cout << test_rational_Instance.report() << endl;
01170     }
01171     if (1) {
01172         test_rational<int>  test_rational_Instance;
01173         test_rational_Instance.setUp();
01174         test_rational_Instance.run();
01175         cout << test_rational_Instance.report() << endl;
01176     }
01177     if (1) {
01178         test_rational<short>  test_rational_Instance;
01179         test_rational_Instance.setUp();
01180         test_rational_Instance.run();
01181         cout << test_rational_Instance.report() << endl;
01182     }
01183     if (0) { int main_viejo(); main_viejo(); }
01184     return 0;
01185 }
01186 
01187 // EOF: test_rational.cpp