123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- ///////////////////////////////////////////////////////////////////////////////
- // Copyright 2022 Matt Borland. 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)
- #ifndef BOOST_MP_DETAIL_FPCLASSIFY_HPP
- #define BOOST_MP_DETAIL_FPCLASSIFY_HPP
- #include <cmath>
- #include <limits>
- #include <type_traits>
- #include <boost/multiprecision/detail/standalone_config.hpp>
- #include <boost/multiprecision/detail/float128_functions.hpp>
- #ifdef BOOST_MP_MATH_AVAILABLE
- #include <boost/math/special_functions/fpclassify.hpp>
- #define BOOST_MP_ISNAN(x) (boost::math::isnan)(x)
- #define BOOST_MP_ISINF(x) (boost::math::isinf)(x)
- #define BOOST_MP_FPCLASSIFY(x) (boost::math::fpclassify)(x)
- #define BOOST_MP_ISFINITE(x) (!(boost::math::isnan)(x) && !(boost::math::isinf)(x))
- #else
- namespace boost { namespace multiprecision { namespace detail {
- template <typename T, typename std::enable_if<std::is_floating_point<T>::value
- #ifdef BOOST_HAS_FLOAT128
- || std::is_same<T, float128_type>::value
- #endif
- , bool>::type = true>
- inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
- {
- BOOST_MP_FLOAT128_USING;
- using std::isnan;
- return static_cast<bool>((isnan)(x));
- }
- template <typename T, typename std::enable_if<!std::is_floating_point<T>::value
- #ifdef BOOST_HAS_FLOAT128
- && !std::is_same<T, float128_type>::value
- #endif
- , bool>::type = true>
- inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
- {
- return x != x;
- }
- template <typename T, typename std::enable_if<std::is_floating_point<T>::value
- #ifdef BOOST_HAS_FLOAT128
- || std::is_same<T, float128_type>::value
- #endif
- , bool>::type = true>
- inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
- {
- BOOST_MP_FLOAT128_USING;
- using std::isinf;
- return static_cast<bool>((isinf)(x));
- }
- template <typename T, typename std::enable_if<!std::is_floating_point<T>::value
- #ifdef BOOST_HAS_FLOAT128
- && !std::is_same<T, float128_type>::value
- #endif
- , bool>::type = true>
- inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
- {
- return x == std::numeric_limits<T>::infinity() || x == -std::numeric_limits<T>::infinity();
- }
- template <typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true>
- inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
- {
- using std::fpclassify;
- return fpclassify(x);
- }
- template <typename T, typename std::enable_if<!std::is_floating_point<T>::value, bool>::type = true>
- inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
- {
- BOOST_MP_FLOAT128_USING;
- using std::isnan;
- using std::isinf;
- using std::abs;
- return (isnan)(x) ? FP_NAN :
- (isinf)(x) ? FP_INFINITE :
- abs(x) == T(0) ? FP_ZERO :
- abs(x) > 0 && abs(x) < (std::numeric_limits<T>::min)() ? FP_SUBNORMAL : FP_NORMAL;
- }
- }}} // Namespace boost::multiprecision::detail
- #define BOOST_MP_ISNAN(x) (boost::multiprecision::detail::isnan)(x)
- #define BOOST_MP_ISINF(x) (boost::multiprecision::detail::isinf)(x)
- #define BOOST_MP_FPCLASSIFY(x) (boost::multiprecision::detail::fpclassify)(x)
- #define BOOST_MP_ISFINITE(x) (!(boost::multiprecision::detail::isnan)(x) && !(boost::multiprecision::detail::isinf)(x))
- #endif
- #endif // BOOST_MP_DETAIL_FPCLASSIFY_HPP
|