• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // boostinspect:nolicense (don't complain about the lack of a Boost license)
9 // (Paul Moore hasn't been in contact for years, so there's no way to change the
10 // license.)
11 
12 //  Revision History
13 //  14 Dec 99  Initial version
14 
15 #include <iostream>
16 #include <cassert>
17 #include <cstdlib>
18 #include <boost/config.hpp>
19 #ifndef BOOST_NO_LIMITS
20 #include <limits>
21 #else
22 #include <limits.h>
23 #endif
24 #include <exception>
25 #include <boost/rational.hpp>
26 
27 using std::cout;
28 using std::endl;
29 using boost::rational;
30 
31 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
32 // This is a nasty hack, required because MSVC does not implement "Koenig
33 // Lookup". Basically, if I call abs(r), the C++ standard says that the
34 // compiler should look for a definition of abs in the namespace which
35 // contains r's class (in this case boost) - among other places.
36 
37 // Koenig Lookup is a relatively recent feature, and other compilers may not
38 // implement it yet. If so, try including this line.
39 
40 using boost::abs;
41 #endif
42 
main()43 int main ()
44 {
45     rational<int> half(1,2);
46     rational<int> one(1);
47     rational<int> two(2);
48 
49     // Some basic checks
50     assert(half.numerator() == 1);
51     assert(half.denominator() == 2);
52     assert(boost::rational_cast<double>(half) == 0.5);
53 
54     // Arithmetic
55     assert(half + half == one);
56     assert(one - half == half);
57     assert(two * half == one);
58     assert(one / half == two);
59 
60     // With conversions to integer
61     assert(half+half == 1);
62     assert(2 * half == one);
63     assert(2 * half == 1);
64     assert(one / half == 2);
65     assert(1 / half == 2);
66 
67     // Sign handling
68     rational<int> minus_half(-1,2);
69     assert(-half == minus_half);
70     assert(abs(minus_half) == half);
71 
72     // Do we avoid overflow?
73 #ifndef BOOST_NO_LIMITS
74     int maxint = (std::numeric_limits<int>::max)();
75 #else
76     int maxint = INT_MAX;
77 #endif
78     rational<int> big(maxint, 2);
79     assert(2 * big == maxint);
80 
81     // Print some of the above results
82     cout << half << "+" << half << "=" << one << endl;
83     cout << one << "-" << half << "=" << half << endl;
84     cout << two << "*" << half << "=" << one << endl;
85     cout << one << "/" << half << "=" << two << endl;
86     cout << "abs(" << minus_half << ")=" << half << endl;
87     cout << "2 * " << big << "=" << maxint
88          << " (rational: " << rational<int>(maxint) << ")" << endl;
89 
90     // Some extras
91     rational<int> pi(22,7);
92     cout << "pi = " << boost::rational_cast<double>(pi) << " (nearly)" << endl;
93 
94     // Exception handling
95     try {
96         rational<int> r;        // Forgot to initialise - set to 0
97         r = 1/r;                // Boom!
98     }
99     catch (const boost::bad_rational &e) {
100         cout << "Bad rational, as expected: " << e.what() << endl;
101     }
102     catch (...) {
103         cout << "Wrong exception raised!" << endl;
104     }
105 
106     return 0;
107 }
108 
109