| 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 |  | 
|---|