test_rational.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //////////////////////////////////////////////////////////////////
  2. // example94.cpp
  3. //
  4. // Copyright (c) 2015 Robert Ramey
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. // illustrate usage of safe<int> as drop-in replacement for int in
  10. // a more complex library. Use an example from the boost.rational
  11. // library with modifications to use safe<int> rather than int
  12. // rational number example program ----------------------------------------//
  13. // (C) Copyright Paul Moore 1999. Permission to copy, use, modify, sell
  14. // and distribute this software is granted provided this copyright notice
  15. // appears in all copies. This software is provided "as is" without express or
  16. // implied warranty, and with no claim as to its suitability for any purpose.
  17. // boostinspect:nolicense (don't complain about the lack of a Boost license)
  18. // (Paul Moore hasn't been in contact for years, so there's no way to change the
  19. // license.)
  20. // Revision History
  21. // 14 Dec 99 Initial version
  22. #include <iostream>
  23. #include <cassert>
  24. #include <cstdlib>
  25. #include <boost/config.hpp>
  26. #include <limits>
  27. #include <exception>
  28. #include <boost/rational.hpp>
  29. #include <boost/safe_numerics/safe_integer.hpp>
  30. using std::cout;
  31. using std::endl;
  32. using boost::rational;
  33. using namespace boost::safe_numerics;
  34. using int_type = safe<int>;
  35. int main ()
  36. {
  37. rational<int_type> half(1,2);
  38. rational<int_type> one(1);
  39. rational<int_type> two(2);
  40. // Some basic checks
  41. assert(half.numerator() == 1);
  42. assert(half.denominator() == 2);
  43. // assert(boost::rational_cast<double>(half) == 0.5);
  44. static_assert(
  45. ! boost::safe_numerics::is_safe<rational<int_type>>::value,
  46. "rational<int_type> is safe"
  47. );
  48. // Arithmetic
  49. assert(half + half == one);
  50. assert(one - half == half);
  51. assert(two * half == one);
  52. assert(one / half == two);
  53. // With conversions to integer
  54. assert(half+half == 1);
  55. assert(2 * half == one);
  56. assert(2 * half == 1);
  57. assert(one / half == 2);
  58. assert(1 / half == 2);
  59. // Sign handling
  60. rational<int_type> minus_half(-1,2);
  61. assert(-half == minus_half);
  62. assert(abs(minus_half) == half);
  63. // Do we avoid overflow?
  64. int maxint = (std::numeric_limits<int>::max)();
  65. rational<int_type> big(maxint, 2);
  66. assert(2 * big == maxint);
  67. // Print some of the above results
  68. cout << half << "+" << half << "=" << one << endl;
  69. cout << one << "-" << half << "=" << half << endl;
  70. cout << two << "*" << half << "=" << one << endl;
  71. cout << one << "/" << half << "=" << two << endl;
  72. cout << "abs(" << minus_half << ")=" << half << endl;
  73. cout << "2 * " << big << "=" << maxint
  74. << " (rational: " << rational<int>(maxint) << ")" << endl;
  75. // Some extras
  76. // rational<int_type> pi(22,7);
  77. // cout << "pi = " << boost::rational_cast<double>(pi) << " (nearly)" << endl;
  78. // Exception handling
  79. try {
  80. rational<int_type> r; // Forgot to initialise - set to 0
  81. r = 1/r; // Boom!
  82. }
  83. catch (const boost::bad_rational &e) {
  84. cout << "Bad rational, as expected: " << e.what() << endl;
  85. }
  86. catch (...) {
  87. cout << "Wrong exception raised!" << endl;
  88. }
  89. return 0;
  90. }