| [29] | 1 | //  rational number example program  ----------------------------------------// | 
|---|
 | 2 |  | 
|---|
 | 3 | //  (C) Copyright Paul Moore 1999. Permission to copy, use, modify, sell | 
|---|
 | 4 | //  and distribute this software is granted provided this copyright notice | 
|---|
 | 5 | //  appears in all copies. This software is provided "as is" without express or | 
|---|
 | 6 | //  implied warranty, and with no claim as to its suitability for any purpose. | 
|---|
 | 7 |  | 
|---|
 | 8 | //  Revision History | 
|---|
 | 9 | //  14 Dec 99  Initial version | 
|---|
 | 10 |  | 
|---|
 | 11 | #include <iostream> | 
|---|
 | 12 | #include <cassert> | 
|---|
 | 13 | #include <cstdlib> | 
|---|
 | 14 | #include <boost/config.hpp> | 
|---|
 | 15 | #ifndef BOOST_NO_LIMITS | 
|---|
 | 16 | #include <limits> | 
|---|
 | 17 | #else | 
|---|
 | 18 | #include <limits.h> | 
|---|
 | 19 | #endif | 
|---|
 | 20 | #include <exception> | 
|---|
 | 21 | #include <boost/rational.hpp> | 
|---|
 | 22 |  | 
|---|
 | 23 | using std::cout; | 
|---|
 | 24 | using std::endl; | 
|---|
 | 25 | using boost::rational; | 
|---|
 | 26 |  | 
|---|
 | 27 | #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | 
|---|
 | 28 | // This is a nasty hack, required because MSVC does not implement "Koenig | 
|---|
 | 29 | // Lookup". Basically, if I call abs(r), the C++ standard says that the | 
|---|
 | 30 | // compiler should look for a definition of abs in the namespace which | 
|---|
 | 31 | // contains r's class (in this case boost) - among other places. | 
|---|
 | 32 |  | 
|---|
 | 33 | // Koenig Lookup is a relatively recent feature, and other compilers may not | 
|---|
 | 34 | // implement it yet. If so, try including this line. | 
|---|
 | 35 |  | 
|---|
 | 36 | using boost::abs; | 
|---|
 | 37 | #endif | 
|---|
 | 38 |  | 
|---|
 | 39 | int main () | 
|---|
 | 40 | { | 
|---|
 | 41 |     rational<int> half(1,2); | 
|---|
 | 42 |     rational<int> one(1); | 
|---|
 | 43 |     rational<int> two(2); | 
|---|
 | 44 |  | 
|---|
 | 45 |     // Some basic checks | 
|---|
 | 46 |     assert(half.numerator() == 1); | 
|---|
 | 47 |     assert(half.denominator() == 2); | 
|---|
 | 48 |     assert(boost::rational_cast<double>(half) == 0.5); | 
|---|
 | 49 |  | 
|---|
 | 50 |     // Arithmetic | 
|---|
 | 51 |     assert(half + half == one); | 
|---|
 | 52 |     assert(one - half == half); | 
|---|
 | 53 |     assert(two * half == one); | 
|---|
 | 54 |     assert(one / half == two); | 
|---|
 | 55 |  | 
|---|
 | 56 |     // With conversions to integer | 
|---|
 | 57 |     assert(half+half == 1); | 
|---|
 | 58 |     assert(2 * half == one); | 
|---|
 | 59 |     assert(2 * half == 1); | 
|---|
 | 60 |     assert(one / half == 2); | 
|---|
 | 61 |     assert(1 / half == 2); | 
|---|
 | 62 |  | 
|---|
 | 63 |     // Sign handling | 
|---|
 | 64 |     rational<int> minus_half(-1,2); | 
|---|
 | 65 |     assert(-half == minus_half); | 
|---|
 | 66 |     assert(abs(minus_half) == half); | 
|---|
 | 67 |  | 
|---|
 | 68 |     // Do we avoid overflow? | 
|---|
 | 69 | #ifndef BOOST_NO_LIMITS | 
|---|
 | 70 |     int maxint = (std::numeric_limits<int>::max)(); | 
|---|
 | 71 | #else | 
|---|
 | 72 |     int maxint = INT_MAX; | 
|---|
 | 73 | #endif | 
|---|
 | 74 |     rational<int> big(maxint, 2); | 
|---|
 | 75 |     assert(2 * big == maxint); | 
|---|
 | 76 |  | 
|---|
 | 77 |     // Print some of the above results | 
|---|
 | 78 |     cout << half << "+" << half << "=" << one << endl; | 
|---|
 | 79 |     cout << one << "-" << half << "=" << half << endl; | 
|---|
 | 80 |     cout << two << "*" << half << "=" << one << endl; | 
|---|
 | 81 |     cout << one << "/" << half << "=" << two << endl; | 
|---|
 | 82 |     cout << "abs(" << minus_half << ")=" << half << endl; | 
|---|
 | 83 |     cout << "2 * " << big << "=" << maxint | 
|---|
 | 84 |          << " (rational: " << rational<int>(maxint) << ")" << endl; | 
|---|
 | 85 |  | 
|---|
 | 86 |     // Some extras | 
|---|
 | 87 |     rational<int> pi(22,7); | 
|---|
 | 88 |     cout << "pi = " << boost::rational_cast<double>(pi) << " (nearly)" << endl; | 
|---|
 | 89 |  | 
|---|
 | 90 |     // Exception handling | 
|---|
 | 91 |     try { | 
|---|
 | 92 |         rational<int> r;        // Forgot to initialise - set to 0 | 
|---|
 | 93 |         r = 1/r;                // Boom! | 
|---|
 | 94 |     } | 
|---|
 | 95 |     catch (const boost::bad_rational &e) { | 
|---|
 | 96 |         cout << "Bad rational, as expected: " << e.what() << endl; | 
|---|
 | 97 |     } | 
|---|
 | 98 |     catch (...) { | 
|---|
 | 99 |         cout << "Wrong exception raised!" << endl; | 
|---|
 | 100 |     } | 
|---|
 | 101 |  | 
|---|
 | 102 |     return 0; | 
|---|
 | 103 | } | 
|---|
 | 104 |  | 
|---|