trunc.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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. using std::floor;
  21. using std::ceil;
  22. return (arg > 0) ? floor(arg) : ceil(arg);
  23. }
  24. } // namespace impl
  25. #ifdef BOOST_MP_MATH_AVAILABLE
  26. template <typename T>
  27. inline long long lltrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  28. {
  29. return boost::math::lltrunc(arg);
  30. }
  31. template <typename T>
  32. inline int itrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  33. {
  34. return boost::math::itrunc(arg);
  35. }
  36. #else
  37. template <typename T>
  38. inline long long lltrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  39. {
  40. T t = boost::multiprecision::detail::impl::trunc(arg);
  41. if (t > LLONG_MAX)
  42. {
  43. BOOST_MP_THROW_EXCEPTION(std::domain_error("arg cannot be converted into a long long"));
  44. }
  45. return static_cast<long long>(t);
  46. }
  47. template <typename T>
  48. inline int itrunc BOOST_PREVENT_MACRO_SUBSTITUTION (const T arg)
  49. {
  50. T t = boost::multiprecision::detail::impl::trunc(arg);
  51. if (t > static_cast<T>(INT_MAX))
  52. {
  53. BOOST_MP_THROW_EXCEPTION(std::domain_error("arg cannot be converted into an int"));
  54. }
  55. return static_cast<int>(t);
  56. }
  57. #endif
  58. }}} // Namespaces
  59. #endif // BOOST_MP_DETAIL_FUNCTIONS_TRUNC_HPP