trunc.hpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2022 Matt Borland. Distributed under the Boost
  3. // 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_MP_DETAIL_FUNCTIONS_TRUNC_HPP
  6. #define BOOST_MP_DETAIL_FUNCTIONS_TRUNC_HPP
  7. #include <cmath>
  8. #include <limits>
  9. #include <stdexcept>
  10. #include <boost/multiprecision/detail/standalone_config.hpp>
  11. #include <boost/multiprecision/detail/no_exceptions_support.hpp>
  12. #ifdef BOOST_MP_MATH_AVAILABLE
  13. #include <boost/math/special_functions/trunc.hpp>
  14. #endif
  15. namespace boost { namespace multiprecision { namespace detail {
  16. namespace impl {
  17. template <typename T>
  18. inline T trunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  19. {
  20. if (arg > 0)
  21. {
  22. using std::floor;
  23. return floor(arg);
  24. }
  25. using std::ceil;
  26. return ceil(arg);}
  27. } // namespace impl
  28. #ifdef BOOST_MP_MATH_AVAILABLE
  29. template <typename T>
  30. inline long long lltrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  31. {
  32. return boost::math::lltrunc(arg);
  33. }
  34. template <typename T>
  35. inline int itrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  36. {
  37. return boost::math::itrunc(arg);
  38. }
  39. #else
  40. template <typename T>
  41. inline long long lltrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  42. {
  43. T t = boost::multiprecision::detail::impl::trunc(arg);
  44. if (t > LLONG_MAX)
  45. {
  46. BOOST_MP_THROW_EXCEPTION(std::domain_error("arg cannot be converted into a long long"));
  47. }
  48. return static_cast<long long>(t);
  49. }
  50. template <typename T>
  51. inline int itrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  52. {
  53. T t = boost::multiprecision::detail::impl::trunc(arg);
  54. if (t > static_cast<T>(INT_MAX))
  55. {
  56. BOOST_MP_THROW_EXCEPTION(std::domain_error("arg cannot be converted into an int"));
  57. }
  58. return static_cast<int>(t);
  59. }
  60. #endif
  61. }}} // Namespaces
  62. #endif // BOOST_MP_DETAIL_FUNCTIONS_TRUNC_HPP