mp_t.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // (C) Copyright John Maddock 2014.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_TOOLS_MP_T
  6. #define BOOST_MATH_TOOLS_MP_T
  7. #ifndef BOOST_MATH_PRECISION
  8. #define BOOST_MATH_PRECISION 1000
  9. #endif
  10. #if defined(BOOST_MATH_USE_MPFR)
  11. #include <boost/multiprecision/mpfr.hpp>
  12. typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<BOOST_MATH_PRECISION *301L / 1000L> > mp_t;
  13. #else
  14. #include <boost/multiprecision/cpp_bin_float.hpp>
  15. typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<BOOST_MATH_PRECISION, boost::multiprecision::digit_base_2> > mp_t;
  16. #endif
  17. inline mp_t ConvPrec(mp_t arg, int digits)
  18. {
  19. int e1, e2;
  20. mp_t t = frexp(arg, &e1);
  21. t = frexp(floor(ldexp(t, digits + 1)), &e2);
  22. return ldexp(t, e1);
  23. }
  24. inline mp_t relative_error(mp_t a, mp_t b)
  25. {
  26. mp_t min_val = boost::math::tools::min_value<mp_t>();
  27. mp_t max_val = boost::math::tools::max_value<mp_t>();
  28. if((a != 0) && (b != 0))
  29. {
  30. // mp_tODO: use isfinite:
  31. if(fabs(b) >= max_val)
  32. {
  33. if(fabs(a) >= max_val)
  34. return 0; // one infinity is as good as another!
  35. }
  36. // If the result is denormalised, treat all denorms as equivalent:
  37. if((a < min_val) && (a > 0))
  38. a = min_val;
  39. else if((a > -min_val) && (a < 0))
  40. a = -min_val;
  41. if((b < min_val) && (b > 0))
  42. b = min_val;
  43. else if((b > -min_val) && (b < 0))
  44. b = -min_val;
  45. return (std::max)(fabs((a - b) / a), fabs((a - b) / b));
  46. }
  47. // Handle special case where one or both are zero:
  48. if(min_val == 0)
  49. return fabs(a - b);
  50. if(fabs(a) < min_val)
  51. a = min_val;
  52. if(fabs(b) < min_val)
  53. b = min_val;
  54. return (std::max)(fabs((a - b) / a), fabs((a - b) / b));
  55. }
  56. #endif // BOOST_MATH_TOOLS_MP_T