Abstract non Polymorphyc Matrix:
|
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