////////////////////////////////////////////////////////////////// // example94.cpp // // Copyright (c) 2015 Robert Ramey // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // illustrate usage of safe as drop-in replacement for int in // a more complex library. Use an example from the boost.rational // library with modifications to use safe rather than int // 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. // boostinspect:nolicense (don't complain about the lack of a Boost license) // (Paul Moore hasn't been in contact for years, so there's no way to change the // license.) // Revision History // 14 Dec 99 Initial version #include #include #include #include #include #include #include #include using std::cout; using std::endl; using boost::rational; using namespace boost::safe_numerics; using int_type = safe; int main () { rational half(1,2); rational one(1); rational two(2); // Some basic checks assert(half.numerator() == 1); assert(half.denominator() == 2); // assert(boost::rational_cast(half) == 0.5); static_assert( ! boost::safe_numerics::is_safe>::value, "rational is safe" ); // 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 minus_half(-1,2); assert(-half == minus_half); assert(abs(minus_half) == half); // Do we avoid overflow? int maxint = (std::numeric_limits::max)(); rational 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(maxint) << ")" << endl; // Some extras // rational pi(22,7); // cout << "pi = " << boost::rational_cast(pi) << " (nearly)" << endl; // Exception handling try { rational 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; }