Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:13

0001 //  Copyright John Maddock 2005-2008.
0002 //  Copyright (c) 2006-2008 Johan Rade
0003 //  Use, modification and distribution are subject to the
0004 //  Boost Software License, Version 1.0. (See accompanying file
0005 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_MATH_FPCLASSIFY_HPP
0008 #define BOOST_MATH_FPCLASSIFY_HPP
0009 
0010 #ifdef _MSC_VER
0011 #pragma once
0012 #endif
0013 
0014 #include <limits>
0015 #include <type_traits>
0016 #include <cmath>
0017 #include <boost/math/tools/real_cast.hpp>
0018 #include <boost/math/special_functions/math_fwd.hpp>
0019 #include <boost/math/special_functions/detail/fp_traits.hpp>
0020 /*!
0021   \file fpclassify.hpp
0022   \brief Classify floating-point value as normal, subnormal, zero, infinite, or NaN.
0023   \version 1.0
0024   \author John Maddock
0025  */
0026 
0027 /*
0028 
0029 1. If the platform is C99 compliant, then the native floating point
0030 classification functions are used.  However, note that we must only
0031 define the functions which call std::fpclassify etc if that function
0032 really does exist: otherwise a compiler may reject the code even though
0033 the template is never instantiated.
0034 
0035 2. If the platform is not C99 compliant, and the binary format for
0036 a floating point type (float, double or long double) can be determined
0037 at compile time, then the following algorithm is used:
0038 
0039         If all exponent bits, the flag bit (if there is one),
0040         and all significand bits are 0, then the number is zero.
0041 
0042         If all exponent bits and the flag bit (if there is one) are 0,
0043         and at least one significand bit is 1, then the number is subnormal.
0044 
0045         If all exponent bits are 1 and all significand bits are 0,
0046         then the number is infinity.
0047 
0048         If all exponent bits are 1 and at least one significand bit is 1,
0049         then the number is a not-a-number.
0050 
0051         Otherwise the number is normal.
0052 
0053         This algorithm works for the IEEE 754 representation,
0054         and also for several non IEEE 754 formats.
0055 
0056     Most formats have the structure
0057         sign bit + exponent bits + significand bits.
0058 
0059     A few have the structure
0060         sign bit + exponent bits + flag bit + significand bits.
0061     The flag bit is 0 for zero and subnormal numbers,
0062         and 1 for normal numbers and NaN.
0063         It is 0 (Motorola 68K) or 1 (Intel) for infinity.
0064 
0065     To get the bits, the four or eight most significant bytes are copied
0066     into an uint32_t or uint64_t and bit masks are applied.
0067     This covers all the exponent bits and the flag bit (if there is one),
0068     but not always all the significand bits.
0069     Some of the functions below have two implementations,
0070     depending on whether all the significand bits are copied or not.
0071 
0072 3. If the platform is not C99 compliant, and the binary format for
0073 a floating point type (float, double or long double) can not be determined
0074 at compile time, then comparison with std::numeric_limits values
0075 is used.
0076 
0077 */
0078 
0079 #if defined(_MSC_VER) || defined(BOOST_BORLANDC)
0080 #include <cfloat>
0081 #endif
0082 #ifdef BOOST_MATH_USE_FLOAT128
0083 #ifdef __has_include
0084 #if  __has_include("quadmath.h")
0085 #include "quadmath.h"
0086 #define BOOST_MATH_HAS_QUADMATH_H
0087 #endif
0088 #endif
0089 #endif
0090 
0091 #ifdef BOOST_NO_STDC_NAMESPACE
0092   namespace std{ using ::abs; using ::fabs; }
0093 #endif
0094 
0095 namespace boost{
0096 
0097 //
0098 // This must not be located in any namespace under boost::math
0099 // otherwise we can get into an infinite loop if isnan is
0100 // a #define for "isnan" !
0101 //
0102 namespace math_detail{
0103 
0104 #ifdef _MSC_VER
0105 #pragma warning(push)
0106 #pragma warning(disable:4800)
0107 #endif
0108 
0109 template <class T>
0110 inline bool is_nan_helper(T t, const std::true_type&)
0111 {
0112 #ifdef isnan
0113    return isnan(t);
0114 #elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY)
0115    (void)t;
0116    return false;
0117 #else // BOOST_HAS_FPCLASSIFY
0118    return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN);
0119 #endif
0120 }
0121 
0122 #ifdef _MSC_VER
0123 #pragma warning(pop)
0124 #endif
0125 
0126 template <class T>
0127 inline bool is_nan_helper(T, const std::false_type&)
0128 {
0129    return false;
0130 }
0131 #if defined(BOOST_MATH_USE_FLOAT128)
0132 #if defined(BOOST_MATH_HAS_QUADMATH_H)
0133 inline bool is_nan_helper(__float128 f, const std::true_type&) { return ::isnanq(f); }
0134 inline bool is_nan_helper(__float128 f, const std::false_type&) { return ::isnanq(f); }
0135 #elif defined(BOOST_GNU_STDLIB) && BOOST_GNU_STDLIB && \
0136       _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
0137 inline bool is_nan_helper(__float128 f, const std::true_type&) { return std::isnan(static_cast<double>(f)); }
0138 inline bool is_nan_helper(__float128 f, const std::false_type&) { return std::isnan(static_cast<double>(f)); }
0139 #else
0140 inline bool is_nan_helper(__float128 f, const std::true_type&) { return boost::math::isnan(static_cast<double>(f)); }
0141 inline bool is_nan_helper(__float128 f, const std::false_type&) { return boost::math::isnan(static_cast<double>(f)); }
0142 #endif
0143 #endif
0144 }
0145 
0146 namespace math{
0147 
0148 namespace detail{
0149 
0150 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0151 template <class T>
0152 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const native_tag&)
0153 {
0154    return (std::fpclassify)(t);
0155 }
0156 #endif
0157 
0158 template <class T>
0159 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<true>&)
0160 {
0161    BOOST_MATH_INSTRUMENT_VARIABLE(t);
0162 
0163    // whenever possible check for Nan's first:
0164 #if defined(BOOST_HAS_FPCLASSIFY)  && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
0165    if(::boost::math_detail::is_nan_helper(t, typename std::is_floating_point<T>::type()))
0166       return FP_NAN;
0167 #elif defined(isnan)
0168    if(boost::math_detail::is_nan_helper(t, typename std::is_floating_point<T>::type()))
0169       return FP_NAN;
0170 #elif defined(_MSC_VER) || defined(BOOST_BORLANDC)
0171    if(::_isnan(boost::math::tools::real_cast<double>(t)))
0172       return FP_NAN;
0173 #endif
0174    // std::fabs broken on a few systems especially for long long!!!!
0175    T at = (t < T(0)) ? -t : t;
0176 
0177    // Use a process of exclusion to figure out
0178    // what kind of type we have, this relies on
0179    // IEEE conforming reals that will treat
0180    // Nan's as unordered.  Some compilers
0181    // don't do this once optimisations are
0182    // turned on, hence the check for nan's above.
0183    if(at <= (std::numeric_limits<T>::max)())
0184    {
0185       if(at >= (std::numeric_limits<T>::min)())
0186          return FP_NORMAL;
0187       return (at != 0) ? FP_SUBNORMAL : FP_ZERO;
0188    }
0189    else if(at > (std::numeric_limits<T>::max)())
0190       return FP_INFINITE;
0191    return FP_NAN;
0192 }
0193 
0194 template <class T>
0195 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<false>&)
0196 {
0197 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0198    if(std::numeric_limits<T>::is_specialized)
0199       return fpclassify_imp(t, generic_tag<true>());
0200 #endif
0201    //
0202    // An unknown type with no numeric_limits support,
0203    // so what are we supposed to do we do here?
0204    //
0205    BOOST_MATH_INSTRUMENT_VARIABLE(t);
0206 
0207    return t == 0 ? FP_ZERO : FP_NORMAL;
0208 }
0209 
0210 template<class T>
0211 int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag)
0212 {
0213    typedef typename fp_traits<T>::type traits;
0214 
0215    BOOST_MATH_INSTRUMENT_VARIABLE(x);
0216 
0217    typename traits::bits a;
0218    traits::get_bits(x,a);
0219    BOOST_MATH_INSTRUMENT_VARIABLE(a);
0220    a &= traits::exponent | traits::flag | traits::significand;
0221    BOOST_MATH_INSTRUMENT_VARIABLE((traits::exponent | traits::flag | traits::significand));
0222    BOOST_MATH_INSTRUMENT_VARIABLE(a);
0223 
0224    if(a <= traits::significand) {
0225       if(a == 0)
0226          return FP_ZERO;
0227       else
0228          return FP_SUBNORMAL;
0229    }
0230 
0231    if(a < traits::exponent) return FP_NORMAL;
0232 
0233    a &= traits::significand;
0234    if(a == 0) return FP_INFINITE;
0235 
0236    return FP_NAN;
0237 }
0238 
0239 template<class T>
0240 int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
0241 {
0242    typedef typename fp_traits<T>::type traits;
0243 
0244    BOOST_MATH_INSTRUMENT_VARIABLE(x);
0245 
0246    typename traits::bits a;
0247    traits::get_bits(x,a);
0248    a &= traits::exponent | traits::flag | traits::significand;
0249 
0250    if(a <= traits::significand) {
0251       if(x == 0)
0252          return FP_ZERO;
0253       else
0254          return FP_SUBNORMAL;
0255    }
0256 
0257    if(a < traits::exponent) return FP_NORMAL;
0258 
0259    a &= traits::significand;
0260    traits::set_bits(x,a);
0261    if(x == 0) return FP_INFINITE;
0262 
0263    return FP_NAN;
0264 }
0265 
0266 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS))
0267 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0268 {
0269    return boost::math::detail::fpclassify_imp(t, generic_tag<true>());
0270 }
0271 #endif
0272 
0273 }  // namespace detail
0274 
0275 template <class T>
0276 inline int fpclassify BOOST_NO_MACRO_EXPAND(T t)
0277 {
0278    typedef typename detail::fp_traits<T>::type traits;
0279    typedef typename traits::method method;
0280    typedef typename tools::promote_args_permissive<T>::type value_type;
0281 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0282    if(std::numeric_limits<T>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(nullptr)))
0283       return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
0284    return detail::fpclassify_imp(static_cast<value_type>(t), method());
0285 #else
0286    return detail::fpclassify_imp(static_cast<value_type>(t), method());
0287 #endif
0288 }
0289 
0290 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0291 template <>
0292 inline int fpclassify<long double> BOOST_NO_MACRO_EXPAND(long double t)
0293 {
0294    typedef detail::fp_traits<long double>::type traits;
0295    typedef traits::method method;
0296    typedef long double value_type;
0297 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0298    if(std::numeric_limits<long double>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(nullptr)))
0299       return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
0300    return detail::fpclassify_imp(static_cast<value_type>(t), method());
0301 #else
0302    return detail::fpclassify_imp(static_cast<value_type>(t), method());
0303 #endif
0304 }
0305 #endif
0306 
0307 namespace detail {
0308 
0309 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0310     template<class T>
0311     inline bool isfinite_impl(T x, native_tag const&)
0312     {
0313         return (std::isfinite)(x);
0314     }
0315 #endif
0316 
0317     template<class T>
0318     inline bool isfinite_impl(T x, generic_tag<true> const&)
0319     {
0320         return x >= -(std::numeric_limits<T>::max)()
0321             && x <= (std::numeric_limits<T>::max)();
0322     }
0323 
0324     template<class T>
0325     inline bool isfinite_impl(T x, generic_tag<false> const&)
0326     {
0327 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0328       if(std::numeric_limits<T>::is_specialized)
0329          return isfinite_impl(x, generic_tag<true>());
0330 #endif
0331        (void)x; // warning suppression.
0332        return true;
0333     }
0334 
0335     template<class T>
0336     inline bool isfinite_impl(T x, ieee_tag const&)
0337     {
0338         typedef typename detail::fp_traits<T>::type traits;
0339         typename traits::bits a;
0340         traits::get_bits(x,a);
0341         a &= traits::exponent;
0342         return a != traits::exponent;
0343     }
0344 
0345 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
0346 inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0347 {
0348    return boost::math::detail::isfinite_impl(t, generic_tag<true>());
0349 }
0350 #endif
0351 
0352 }
0353 
0354 template<class T>
0355 inline bool (isfinite)(T x)
0356 { //!< \brief return true if floating-point type t is finite.
0357    typedef typename detail::fp_traits<T>::type traits;
0358    typedef typename traits::method method;
0359    // typedef typename boost::is_floating_point<T>::type fp_tag;
0360    typedef typename tools::promote_args_permissive<T>::type value_type;
0361    return detail::isfinite_impl(static_cast<value_type>(x), method());
0362 }
0363 
0364 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0365 template<>
0366 inline bool (isfinite)(long double x)
0367 { //!< \brief return true if floating-point type t is finite.
0368    typedef detail::fp_traits<long double>::type traits;
0369    typedef traits::method method;
0370    //typedef boost::is_floating_point<long double>::type fp_tag;
0371    typedef long double value_type;
0372    return detail::isfinite_impl(static_cast<value_type>(x), method());
0373 }
0374 #endif
0375 
0376 //------------------------------------------------------------------------------
0377 
0378 namespace detail {
0379 
0380 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0381     template<class T>
0382     inline bool isnormal_impl(T x, native_tag const&)
0383     {
0384         return (std::isnormal)(x);
0385     }
0386 #endif
0387 
0388     template<class T>
0389     inline bool isnormal_impl(T x, generic_tag<true> const&)
0390     {
0391         if(x < 0) x = -x;
0392         return x >= (std::numeric_limits<T>::min)()
0393             && x <= (std::numeric_limits<T>::max)();
0394     }
0395 
0396     template<class T>
0397     inline bool isnormal_impl(T x, generic_tag<false> const&)
0398     {
0399 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0400       if(std::numeric_limits<T>::is_specialized)
0401          return isnormal_impl(x, generic_tag<true>());
0402 #endif
0403        return !(x == 0);
0404     }
0405 
0406     template<class T>
0407     inline bool isnormal_impl(T x, ieee_tag const&)
0408     {
0409         typedef typename detail::fp_traits<T>::type traits;
0410         typename traits::bits a;
0411         traits::get_bits(x,a);
0412         a &= traits::exponent | traits::flag;
0413         return (a != 0) && (a < traits::exponent);
0414     }
0415 
0416 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
0417 inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0418 {
0419    return boost::math::detail::isnormal_impl(t, generic_tag<true>());
0420 }
0421 #endif
0422 
0423 }
0424 
0425 template<class T>
0426 inline bool (isnormal)(T x)
0427 {
0428    typedef typename detail::fp_traits<T>::type traits;
0429    typedef typename traits::method method;
0430    //typedef typename boost::is_floating_point<T>::type fp_tag;
0431    typedef typename tools::promote_args_permissive<T>::type value_type;
0432    return detail::isnormal_impl(static_cast<value_type>(x), method());
0433 }
0434 
0435 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0436 template<>
0437 inline bool (isnormal)(long double x)
0438 {
0439    typedef detail::fp_traits<long double>::type traits;
0440    typedef traits::method method;
0441    //typedef boost::is_floating_point<long double>::type fp_tag;
0442    typedef long double value_type;
0443    return detail::isnormal_impl(static_cast<value_type>(x), method());
0444 }
0445 #endif
0446 
0447 //------------------------------------------------------------------------------
0448 
0449 namespace detail {
0450 
0451 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0452     template<class T>
0453     inline bool isinf_impl(T x, native_tag const&)
0454     {
0455         return (std::isinf)(x);
0456     }
0457 #endif
0458 
0459     template<class T>
0460     inline bool isinf_impl(T x, generic_tag<true> const&)
0461     {
0462         (void)x; // in case the compiler thinks that x is unused because std::numeric_limits<T>::has_infinity is false
0463         return std::numeric_limits<T>::has_infinity
0464             && ( x == std::numeric_limits<T>::infinity()
0465                  || x == -std::numeric_limits<T>::infinity());
0466     }
0467 
0468     template<class T>
0469     inline bool isinf_impl(T x, generic_tag<false> const&)
0470     {
0471 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0472       if(std::numeric_limits<T>::is_specialized)
0473          return isinf_impl(x, generic_tag<true>());
0474 #endif
0475         (void)x; // warning suppression.
0476         return false;
0477     }
0478 
0479     template<class T>
0480     inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&)
0481     {
0482         typedef typename fp_traits<T>::type traits;
0483 
0484         typename traits::bits a;
0485         traits::get_bits(x,a);
0486         a &= traits::exponent | traits::significand;
0487         return a == traits::exponent;
0488     }
0489 
0490     template<class T>
0491     inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&)
0492     {
0493         typedef typename fp_traits<T>::type traits;
0494 
0495         typename traits::bits a;
0496         traits::get_bits(x,a);
0497         a &= traits::exponent | traits::significand;
0498         if(a != traits::exponent)
0499             return false;
0500 
0501         traits::set_bits(x,0);
0502         return x == 0;
0503     }
0504 
0505 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
0506 inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0507 {
0508    return boost::math::detail::isinf_impl(t, generic_tag<true>());
0509 }
0510 #endif
0511 
0512 }   // namespace detail
0513 
0514 template<class T>
0515 inline bool (isinf)(T x)
0516 {
0517    typedef typename detail::fp_traits<T>::type traits;
0518    typedef typename traits::method method;
0519    // typedef typename boost::is_floating_point<T>::type fp_tag;
0520    typedef typename tools::promote_args_permissive<T>::type value_type;
0521    return detail::isinf_impl(static_cast<value_type>(x), method());
0522 }
0523 
0524 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0525 template<>
0526 inline bool (isinf)(long double x)
0527 {
0528    typedef detail::fp_traits<long double>::type traits;
0529    typedef traits::method method;
0530    //typedef boost::is_floating_point<long double>::type fp_tag;
0531    typedef long double value_type;
0532    return detail::isinf_impl(static_cast<value_type>(x), method());
0533 }
0534 #endif
0535 #if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
0536 template<>
0537 inline bool (isinf)(__float128 x)
0538 {
0539    return ::isinfq(x);
0540 }
0541 #endif
0542 
0543 //------------------------------------------------------------------------------
0544 
0545 namespace detail {
0546 
0547 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0548     template<class T>
0549     inline bool isnan_impl(T x, native_tag const&)
0550     {
0551         return (std::isnan)(x);
0552     }
0553 #endif
0554 
0555     template<class T>
0556     inline bool isnan_impl(T x, generic_tag<true> const&)
0557     {
0558         return std::numeric_limits<T>::has_infinity
0559             ? !(x <= std::numeric_limits<T>::infinity())
0560             : x != x;
0561     }
0562 
0563     template<class T>
0564     inline bool isnan_impl(T x, generic_tag<false> const&)
0565     {
0566 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0567       if(std::numeric_limits<T>::is_specialized)
0568          return isnan_impl(x, generic_tag<true>());
0569 #endif
0570         (void)x; // warning suppression
0571         return false;
0572     }
0573 
0574     template<class T>
0575     inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&)
0576     {
0577         typedef typename fp_traits<T>::type traits;
0578 
0579         typename traits::bits a;
0580         traits::get_bits(x,a);
0581         a &= traits::exponent | traits::significand;
0582         return a > traits::exponent;
0583     }
0584 
0585     template<class T>
0586     inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&)
0587     {
0588         typedef typename fp_traits<T>::type traits;
0589 
0590         typename traits::bits a;
0591         traits::get_bits(x,a);
0592 
0593         a &= traits::exponent | traits::significand;
0594         if(a < traits::exponent)
0595             return false;
0596 
0597         a &= traits::significand;
0598         traits::set_bits(x,a);
0599         return x != 0;
0600     }
0601 
0602 }   // namespace detail
0603 
0604 template<class T>
0605 inline bool (isnan)(T x)
0606 { //!< \brief return true if floating-point type t is NaN (Not A Number).
0607    typedef typename detail::fp_traits<T>::type traits;
0608    typedef typename traits::method method;
0609    // typedef typename boost::is_floating_point<T>::type fp_tag;
0610    return detail::isnan_impl(x, method());
0611 }
0612 
0613 #ifdef isnan
0614 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<float>(float t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); }
0615 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<double>(double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); }
0616 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<long double>(long double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); }
0617 #elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
0618 template<>
0619 inline bool (isnan)(long double x)
0620 { //!< \brief return true if floating-point type t is NaN (Not A Number).
0621    typedef detail::fp_traits<long double>::type traits;
0622    typedef traits::method method;
0623    //typedef boost::is_floating_point<long double>::type fp_tag;
0624    return detail::isnan_impl(x, method());
0625 }
0626 #endif
0627 #if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
0628 template<>
0629 inline bool (isnan)(__float128 x)
0630 {
0631    return ::isnanq(x);
0632 }
0633 #endif
0634 
0635 } // namespace math
0636 } // namespace boost
0637 #endif // BOOST_MATH_FPCLASSIFY_HPP
0638