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