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