X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Fmath%2Fspecial_functions%2Ffpclassify.hpp;fp=boost%2Fmath%2Fspecial_functions%2Ffpclassify.hpp;h=75f57b03b862a780351c66b1109d0085434af513;hp=d3dc42b0caf6ba98fe4d6e51d6f09288b5745ecb;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/math/special_functions/fpclassify.hpp b/boost/math/special_functions/fpclassify.hpp index d3dc42b..75f57b0 100644 --- a/boost/math/special_functions/fpclassify.hpp +++ b/boost/math/special_functions/fpclassify.hpp @@ -37,13 +37,13 @@ the template is never instantiated. a floating point type (float, double or long double) can be determined at compile time, then the following algorithm is used: - If all exponent bits, the flag bit (if there is one), + If all exponent bits, the flag bit (if there is one), and all significand bits are 0, then the number is zero. - If all exponent bits and the flag bit (if there is one) are 0, + If all exponent bits and the flag bit (if there is one) are 0, and at least one significand bit is 1, then the number is subnormal. - If all exponent bits are 1 and all significand bits are 0, + If all exponent bits are 1 and all significand bits are 0, then the number is infinity. If all exponent bits are 1 and at least one significand bit is 1, @@ -56,7 +56,7 @@ at compile time, then the following algorithm is used: Most formats have the structure sign bit + exponent bits + significand bits. - + A few have the structure sign bit + exponent bits + flag bit + significand bits. The flag bit is 0 for zero and subnormal numbers, @@ -85,9 +85,8 @@ is used. namespace std{ using ::abs; using ::fabs; } #endif -namespace boost{ +namespace boost{ -#if defined(BOOST_HAS_FPCLASSIFY) || defined(isnan) // // This must not be located in any namespace under boost::math // otherwise we can get into an infinite loop if isnan is @@ -95,16 +94,28 @@ namespace boost{ // namespace math_detail{ +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4800) +#endif + template inline bool is_nan_helper(T t, const boost::true_type&) { #ifdef isnan return isnan(t); +#elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY) + (void)t; + return false; #else // BOOST_HAS_FPCLASSIFY return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN); #endif } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + template inline bool is_nan_helper(T, const boost::false_type&) { @@ -113,8 +124,6 @@ inline bool is_nan_helper(T, const boost::false_type&) } -#endif // defined(BOOST_HAS_FPCLASSIFY) || defined(isnan) - namespace math{ namespace detail{ @@ -133,7 +142,7 @@ inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag&) BOOST_MATH_INSTRUMENT_VARIABLE(t); // whenever possible check for Nan's first: -#ifdef BOOST_HAS_FPCLASSIFY +#if defined(BOOST_HAS_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) if(::boost::math_detail::is_nan_helper(t, ::boost::is_floating_point())) return FP_NAN; #elif defined(isnan) @@ -168,9 +177,9 @@ inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag&) { #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS if(std::numeric_limits::is_specialized) - return fp_classify_imp(t, mpl::true_()); + return fpclassify_imp(t, generic_tag()); #endif - // + // // An unknown type with no numeric_limits support, // so what are we supposed to do we do here? // @@ -179,7 +188,7 @@ inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag&) return t == 0 ? FP_ZERO : FP_NORMAL; } -template +template int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag) { typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; @@ -208,7 +217,7 @@ int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag) return FP_NAN; } -template +template int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag) { typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; @@ -216,7 +225,7 @@ int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag) BOOST_MATH_INSTRUMENT_VARIABLE(x); BOOST_DEDUCED_TYPENAME traits::bits a; - traits::get_bits(x,a); + traits::get_bits(x,a); a &= traits::exponent | traits::flag | traits::significand; if(a <= traits::significand) { @@ -235,9 +244,8 @@ int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag) return FP_NAN; } -#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) -template <> -inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)) +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) { return boost::math::detail::fpclassify_imp(t, generic_tag()); } @@ -250,44 +258,62 @@ inline int fpclassify BOOST_NO_MACRO_EXPAND(T t) { typedef typename detail::fp_traits::type traits; typedef typename traits::method method; + typedef typename tools::promote_args_permissive::type value_type; #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(method())) - return detail::fpclassify_imp(t, detail::generic_tag()); - return detail::fpclassify_imp(t, method()); + if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(static_cast(0))) + return detail::fpclassify_imp(static_cast(t), detail::generic_tag()); + return detail::fpclassify_imp(static_cast(t), method()); #else - return detail::fpclassify_imp(t, method()); + return detail::fpclassify_imp(static_cast(t), method()); #endif } +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template <> +inline int fpclassify BOOST_NO_MACRO_EXPAND(long double t) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + typedef long double value_type; +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(static_cast(0))) + return detail::fpclassify_imp(static_cast(t), detail::generic_tag()); + return detail::fpclassify_imp(static_cast(t), method()); +#else + return detail::fpclassify_imp(static_cast(t), method()); +#endif +} +#endif + namespace detail { #ifdef BOOST_MATH_USE_STD_FPCLASSIFY - template + template inline bool isfinite_impl(T x, native_tag const&) { return (std::isfinite)(x); } #endif - template + template inline bool isfinite_impl(T x, generic_tag const&) { return x >= -(std::numeric_limits::max)() && x <= (std::numeric_limits::max)(); } - template + template inline bool isfinite_impl(T x, generic_tag const&) { #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS if(std::numeric_limits::is_specialized) - return isfinite_impl(x, mpl::true_()); + return isfinite_impl(x, generic_tag()); #endif (void)x; // warning supression. return true; } - template + template inline bool isfinite_impl(T x, ieee_tag const&) { typedef BOOST_DEDUCED_TYPENAME detail::fp_traits::type traits; @@ -298,8 +324,7 @@ namespace detail { } #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) -template <> -inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) { return boost::math::detail::isfinite_impl(t, generic_tag()); } @@ -307,28 +332,41 @@ inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, cons } -template +template inline bool (isfinite)(T x) { //!< \brief return true if floating-point type t is finite. typedef typename detail::fp_traits::type traits; typedef typename traits::method method; - typedef typename boost::is_floating_point::type fp_tag; - return detail::isfinite_impl(x, method()); + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isfinite_impl(static_cast(x), method()); } +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isfinite)(long double x) +{ //!< \brief return true if floating-point type t is finite. + typedef detail::fp_traits::type traits; + typedef traits::method method; + typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isfinite_impl(static_cast(x), method()); +} +#endif + //------------------------------------------------------------------------------ namespace detail { #ifdef BOOST_MATH_USE_STD_FPCLASSIFY - template + template inline bool isnormal_impl(T x, native_tag const&) { return (std::isnormal)(x); } #endif - template + template inline bool isnormal_impl(T x, generic_tag const&) { if(x < 0) x = -x; @@ -336,17 +374,17 @@ namespace detail { && x <= (std::numeric_limits::max)(); } - template + template inline bool isnormal_impl(T x, generic_tag const&) { #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS if(std::numeric_limits::is_specialized) - return isnormal_impl(x, mpl::true_()); + return isnormal_impl(x, generic_tag()); #endif return !(x == 0); } - template + template inline bool isnormal_impl(T x, ieee_tag const&) { typedef BOOST_DEDUCED_TYPENAME detail::fp_traits::type traits; @@ -357,8 +395,7 @@ namespace detail { } #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) -template <> -inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) { return boost::math::detail::isnormal_impl(t, generic_tag()); } @@ -366,48 +403,61 @@ inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, cons } -template +template inline bool (isnormal)(T x) { typedef typename detail::fp_traits::type traits; typedef typename traits::method method; - typedef typename boost::is_floating_point::type fp_tag; - return detail::isnormal_impl(x, method()); + //typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isnormal_impl(static_cast(x), method()); } +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isnormal)(long double x) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isnormal_impl(static_cast(x), method()); +} +#endif + //------------------------------------------------------------------------------ namespace detail { #ifdef BOOST_MATH_USE_STD_FPCLASSIFY - template + template inline bool isinf_impl(T x, native_tag const&) { return (std::isinf)(x); } #endif - template + template inline bool isinf_impl(T x, generic_tag const&) { (void)x; // in case the compiler thinks that x is unused because std::numeric_limits::has_infinity is false - return std::numeric_limits::has_infinity + return std::numeric_limits::has_infinity && ( x == std::numeric_limits::infinity() || x == -std::numeric_limits::infinity()); } - template + template inline bool isinf_impl(T x, generic_tag const&) { #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS if(std::numeric_limits::is_specialized) - return isinf_impl(x, mpl::true_()); + return isinf_impl(x, generic_tag()); #endif (void)x; // warning supression. return false; } - template + template inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&) { typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; @@ -418,7 +468,7 @@ namespace detail { return a == traits::exponent; } - template + template inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&) { typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; @@ -434,8 +484,7 @@ namespace detail { } #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) -template <> -inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) { return boost::math::detail::isinf_impl(t, generic_tag()); } @@ -443,28 +492,41 @@ inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const n } // namespace detail -template +template inline bool (isinf)(T x) { typedef typename detail::fp_traits::type traits; typedef typename traits::method method; - typedef typename boost::is_floating_point::type fp_tag; - return detail::isinf_impl(x, method()); + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isinf_impl(static_cast(x), method()); } +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isinf)(long double x) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isinf_impl(static_cast(x), method()); +} +#endif + //------------------------------------------------------------------------------ namespace detail { #ifdef BOOST_MATH_USE_STD_FPCLASSIFY - template + template inline bool isnan_impl(T x, native_tag const&) { return (std::isnan)(x); } #endif - template + template inline bool isnan_impl(T x, generic_tag const&) { return std::numeric_limits::has_infinity @@ -472,18 +534,18 @@ namespace detail { : x != x; } - template + template inline bool isnan_impl(T x, generic_tag const&) { #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS if(std::numeric_limits::is_specialized) - return isnan_impl(x, mpl::true_()); + return isnan_impl(x, generic_tag()); #endif (void)x; // warning supression return false; } - template + template inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&) { typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; @@ -494,7 +556,7 @@ namespace detail { return a > traits::exponent; } - template + template inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&) { typedef BOOST_DEDUCED_TYPENAME fp_traits::type traits; @@ -513,11 +575,12 @@ namespace detail { } // namespace detail -template bool (isnan)(T x) +template +inline bool (isnan)(T x) { //!< \brief return true if floating-point type t is NaN (Not A Number). typedef typename detail::fp_traits::type traits; typedef typename traits::method method; - typedef typename boost::is_floating_point::type fp_tag; + // typedef typename boost::is_floating_point::type fp_tag; return detail::isnan_impl(x, method()); } @@ -525,6 +588,15 @@ template bool (isnan)(T x) template <> inline bool isnan BOOST_NO_MACRO_EXPAND(float t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); } template <> inline bool isnan BOOST_NO_MACRO_EXPAND(double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); } template <> inline bool isnan BOOST_NO_MACRO_EXPAND(long double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); } +#elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +template<> +inline bool (isnan)(long double x) +{ //!< \brief return true if floating-point type t is NaN (Not A Number). + typedef detail::fp_traits::type traits; + typedef traits::method method; + typedef boost::is_floating_point::type fp_tag; + return detail::isnan_impl(x, method()); +} #endif } // namespace math