// rational number example program ----------------------------------------// // (C) Copyright Paul Moore 1999. Permission to copy, use, modify, sell // and distribute this software is granted provided this copyright notice // appears in all copies. This software is provided "as is" without express or // implied warranty, and with no claim as to its suitability for any purpose. // Revision History // 14 Dec 99 Initial version #include <iostream> #include <cassert> #include <cstdlib> #include <boost/config.hpp> #ifndef BOOST_NO_LIMITS #include <limits> #else #include <limits.h> #endif #include <exception> #include <boost/rational.hpp> using std::cout; using std::endl; using boost::rational; #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP // This is a nasty hack, required because MSVC does not implement "Koenig // Lookup". Basically, if I call abs(r), the C++ standard says that the // compiler should look for a definition of abs in the namespace which // contains r's class (in this case boost) - among other places. // Koenig Lookup is a relatively recent feature, and other compilers may not // implement it yet. If so, try including this line. using boost::abs; #endif int main () { rational<int> half(1,2); rational<int> one(1); rational<int> two(2); // Some basic checks assert(half.numerator() == 1); assert(half.denominator() == 2); assert(boost::rational_cast<double>(half) == 0.5); // Arithmetic assert(half + half == one); assert(one - half == half); assert(two * half == one); assert(one / half == two); // With conversions to integer assert(half+half == 1); assert(2 * half == one); assert(2 * half == 1); assert(one / half == 2); assert(1 / half == 2); // Sign handling rational<int> minus_half(-1,2); assert(-half == minus_half); assert(abs(minus_half) == half); // Do we avoid overflow? #ifndef BOOST_NO_LIMITS int maxint = (std::numeric_limits<int>::max)(); #else int maxint = INT_MAX; #endif rational<int> big(maxint, 2); assert(2 * big == maxint); // Print some of the above results cout << half << "+" << half << "=" << one << endl; cout << one << "-" << half << "=" << half << endl; cout << two << "*" << half << "=" << one << endl; cout << one << "/" << half << "=" << two << endl; cout << "abs(" << minus_half << ")=" << half << endl; cout << "2 * " << big << "=" << maxint << " (rational: " << rational<int>(maxint) << ")" << endl; // Some extras rational<int> pi(22,7); cout << "pi = " << boost::rational_cast<double>(pi) << " (nearly)" << endl; // Exception handling try { rational<int> r; // Forgot to initialise - set to 0 r = 1/r; // Boom! } catch (const boost::bad_rational &e) { cout << "Bad rational, as expected: " << e.what() << endl; } catch (...) { cout << "Wrong exception raised!" << endl; } return 0; }