blob: 1438d30bf93de2190fb6a44459807b8fde1c654a [file] [log] [blame]
// 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;
}