File indexing completed on 2025-01-18 09:42:21
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MP_DETAIL_FPCLASSIFY_HPP
0007 #define BOOST_MP_DETAIL_FPCLASSIFY_HPP
0008
0009 #include <cmath>
0010 #include <limits>
0011 #include <type_traits>
0012 #include <boost/multiprecision/detail/standalone_config.hpp>
0013 #include <boost/multiprecision/detail/float128_functions.hpp>
0014
0015 #ifdef BOOST_MP_MATH_AVAILABLE
0016 #include <boost/math/special_functions/fpclassify.hpp>
0017
0018 #define BOOST_MP_ISNAN(x) (boost::math::isnan)(x)
0019 #define BOOST_MP_ISINF(x) (boost::math::isinf)(x)
0020 #define BOOST_MP_FPCLASSIFY(x) (boost::math::fpclassify)(x)
0021 #define BOOST_MP_ISFINITE(x) (!(boost::math::isnan)(x) && !(boost::math::isinf)(x))
0022
0023 #else
0024
0025 namespace boost { namespace multiprecision { namespace detail {
0026
0027 template <typename T, typename std::enable_if<std::is_floating_point<T>::value
0028 #ifdef BOOST_HAS_FLOAT128
0029 || std::is_same<T, float128_type>::value
0030 #endif
0031 , bool>::type = true>
0032 inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
0033 {
0034 BOOST_MP_FLOAT128_USING;
0035 using std::isnan;
0036 return static_cast<bool>((isnan)(x));
0037 }
0038
0039 template <typename T, typename std::enable_if<!std::is_floating_point<T>::value
0040 #ifdef BOOST_HAS_FLOAT128
0041 && !std::is_same<T, float128_type>::value
0042 #endif
0043 , bool>::type = true>
0044 inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
0045 {
0046 return x != x;
0047 }
0048
0049 template <typename T, typename std::enable_if<std::is_floating_point<T>::value
0050 #ifdef BOOST_HAS_FLOAT128
0051 || std::is_same<T, float128_type>::value
0052 #endif
0053 , bool>::type = true>
0054 inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
0055 {
0056 BOOST_MP_FLOAT128_USING;
0057 using std::isinf;
0058 return static_cast<bool>((isinf)(x));
0059 }
0060
0061 template <typename T, typename std::enable_if<!std::is_floating_point<T>::value
0062 #ifdef BOOST_HAS_FLOAT128
0063 && !std::is_same<T, float128_type>::value
0064 #endif
0065 , bool>::type = true>
0066 inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
0067 {
0068 return x == std::numeric_limits<T>::infinity() || x == -std::numeric_limits<T>::infinity();
0069 }
0070
0071 template <typename T, typename std::enable_if<std::is_floating_point<T>::value, bool>::type = true>
0072 inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
0073 {
0074 using std::fpclassify;
0075 return fpclassify(x);
0076 }
0077
0078 template <typename T, typename std::enable_if<!std::is_floating_point<T>::value, bool>::type = true>
0079 inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const T x)
0080 {
0081 BOOST_MP_FLOAT128_USING;
0082 using std::isnan;
0083 using std::isinf;
0084 using std::abs;
0085
0086 return (isnan)(x) ? FP_NAN :
0087 (isinf)(x) ? FP_INFINITE :
0088 abs(x) == T(0) ? FP_ZERO :
0089 abs(x) > 0 && abs(x) < (std::numeric_limits<T>::min)() ? FP_SUBNORMAL : FP_NORMAL;
0090 }
0091
0092 }}}
0093
0094 #define BOOST_MP_ISNAN(x) (boost::multiprecision::detail::isnan)(x)
0095 #define BOOST_MP_ISINF(x) (boost::multiprecision::detail::isinf)(x)
0096 #define BOOST_MP_FPCLASSIFY(x) (boost::multiprecision::detail::fpclassify)(x)
0097 #define BOOST_MP_ISFINITE(x) (!(boost::multiprecision::detail::isnan)(x) && !(boost::multiprecision::detail::isinf)(x))
0098
0099 #endif
0100
0101 #endif