LCOV - code coverage report
Current view: top level - usr/include/boost/math/special_functions - fpclassify.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 8 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //  Copyright John Maddock 2005-2008.
       2             : //  Copyright (c) 2006-2008 Johan Rade
       3             : //  Use, modification and distribution are subject to the
       4             : //  Boost Software License, Version 1.0. (See accompanying file
       5             : //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6             : 
       7             : #ifndef BOOST_MATH_FPCLASSIFY_HPP
       8             : #define BOOST_MATH_FPCLASSIFY_HPP
       9             : 
      10             : #ifdef _MSC_VER
      11             : #pragma once
      12             : #endif
      13             : 
      14             : #include <math.h>
      15             : #include <boost/config/no_tr1/cmath.hpp>
      16             : #include <boost/limits.hpp>
      17             : #include <boost/math/tools/real_cast.hpp>
      18             : #include <boost/type_traits/is_floating_point.hpp>
      19             : #include <boost/math/special_functions/math_fwd.hpp>
      20             : #include <boost/math/special_functions/detail/fp_traits.hpp>
      21             : /*!
      22             :   \file fpclassify.hpp
      23             :   \brief Classify floating-point value as normal, subnormal, zero, infinite, or NaN.
      24             :   \version 1.0
      25             :   \author John Maddock
      26             :  */
      27             : 
      28             : /*
      29             : 
      30             : 1. If the platform is C99 compliant, then the native floating point
      31             : classification functions are used.  However, note that we must only
      32             : define the functions which call std::fpclassify etc if that function
      33             : really does exist: otherwise a compiler may reject the code even though
      34             : the template is never instantiated.
      35             : 
      36             : 2. If the platform is not C99 compliant, and the binary format for
      37             : a floating point type (float, double or long double) can be determined
      38             : at compile time, then the following algorithm is used:
      39             : 
      40             :         If all exponent bits, the flag bit (if there is one),
      41             :         and all significand bits are 0, then the number is zero.
      42             : 
      43             :         If all exponent bits and the flag bit (if there is one) are 0,
      44             :         and at least one significand bit is 1, then the number is subnormal.
      45             : 
      46             :         If all exponent bits are 1 and all significand bits are 0,
      47             :         then the number is infinity.
      48             : 
      49             :         If all exponent bits are 1 and at least one significand bit is 1,
      50             :         then the number is a not-a-number.
      51             : 
      52             :         Otherwise the number is normal.
      53             : 
      54             :         This algorithm works for the IEEE 754 representation,
      55             :         and also for several non IEEE 754 formats.
      56             : 
      57             :     Most formats have the structure
      58             :         sign bit + exponent bits + significand bits.
      59             : 
      60             :     A few have the structure
      61             :         sign bit + exponent bits + flag bit + significand bits.
      62             :     The flag bit is 0 for zero and subnormal numbers,
      63             :         and 1 for normal numbers and NaN.
      64             :         It is 0 (Motorola 68K) or 1 (Intel) for infinity.
      65             : 
      66             :     To get the bits, the four or eight most significant bytes are copied
      67             :     into an uint32_t or uint64_t and bit masks are applied.
      68             :     This covers all the exponent bits and the flag bit (if there is one),
      69             :     but not always all the significand bits.
      70             :     Some of the functions below have two implementations,
      71             :     depending on whether all the significand bits are copied or not.
      72             : 
      73             : 3. If the platform is not C99 compliant, and the binary format for
      74             : a floating point type (float, double or long double) can not be determined
      75             : at compile time, then comparison with std::numeric_limits values
      76             : is used.
      77             : 
      78             : */
      79             : 
      80             : #if defined(_MSC_VER) || defined(__BORLANDC__)
      81             : #include <float.h>
      82             : #endif
      83             : #ifdef BOOST_MATH_USE_FLOAT128
      84             : #ifdef __has_include
      85             : #if  __has_include("quadmath.h")
      86             : #include "quadmath.h"
      87             : #define BOOST_MATH_HAS_QUADMATH_H
      88             : #endif
      89             : #endif
      90             : #endif
      91             : 
      92             : #ifdef BOOST_NO_STDC_NAMESPACE
      93             :   namespace std{ using ::abs; using ::fabs; }
      94             : #endif
      95             : 
      96             : namespace boost{
      97             : 
      98             : //
      99             : // This must not be located in any namespace under boost::math
     100             : // otherwise we can get into an infinite loop if isnan is
     101             : // a #define for "isnan" !
     102             : //
     103             : namespace math_detail{
     104             : 
     105             : #ifdef BOOST_MSVC
     106             : #pragma warning(push)
     107             : #pragma warning(disable:4800)
     108             : #endif
     109             : 
     110             : template <class T>
     111             : inline bool is_nan_helper(T t, const boost::true_type&)
     112             : {
     113             : #ifdef isnan
     114             :    return isnan(t);
     115             : #elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY)
     116             :    (void)t;
     117             :    return false;
     118             : #else // BOOST_HAS_FPCLASSIFY
     119             :    return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN);
     120             : #endif
     121             : }
     122             : 
     123             : #ifdef BOOST_MSVC
     124             : #pragma warning(pop)
     125             : #endif
     126             : 
     127             : template <class T>
     128             : inline bool is_nan_helper(T, const boost::false_type&)
     129             : {
     130             :    return false;
     131             : }
     132             : #if defined(BOOST_MATH_USE_FLOAT128) 
     133             : #if defined(BOOST_MATH_HAS_QUADMATH_H)
     134             : inline bool is_nan_helper(__float128 f, const boost::true_type&) { return ::isnanq(f); }
     135             : inline bool is_nan_helper(__float128 f, const boost::false_type&) { return ::isnanq(f); }
     136             : #elif defined(BOOST_GNU_STDLIB) && BOOST_GNU_STDLIB && \
     137             :       _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
     138             : inline bool is_nan_helper(__float128 f, const boost::true_type&) { return std::isnan(static_cast<double>(f)); }
     139             : inline bool is_nan_helper(__float128 f, const boost::false_type&) { return std::isnan(static_cast<double>(f)); }
     140             : #else
     141             : inline bool is_nan_helper(__float128 f, const boost::true_type&) { return ::isnan(static_cast<double>(f)); }
     142             : inline bool is_nan_helper(__float128 f, const boost::false_type&) { return ::isnan(static_cast<double>(f)); }
     143             : #endif
     144             : #endif
     145             : }
     146             : 
     147             : namespace math{
     148             : 
     149             : namespace detail{
     150             : 
     151             : #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
     152             : template <class T>
     153             : inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const native_tag&)
     154             : {
     155             :    return (std::fpclassify)(t);
     156             : }
     157             : #endif
     158             : 
     159             : template <class T>
     160             : inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<true>&)
     161             : {
     162             :    BOOST_MATH_INSTRUMENT_VARIABLE(t);
     163             : 
     164             :    // whenever possible check for Nan's first:
     165             : #if defined(BOOST_HAS_FPCLASSIFY)  && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
     166             :    if(::boost::math_detail::is_nan_helper(t, ::boost::is_floating_point<T>()))
     167             :       return FP_NAN;
     168             : #elif defined(isnan)
     169             :    if(boost::math_detail::is_nan_helper(t, ::boost::is_floating_point<T>()))
     170             :       return FP_NAN;
     171             : #elif defined(_MSC_VER) || defined(__BORLANDC__)
     172             :    if(::_isnan(boost::math::tools::real_cast<double>(t)))
     173             :       return FP_NAN;
     174             : #endif
     175             :    // std::fabs broken on a few systems especially for long long!!!!
     176             :    T at = (t < T(0)) ? -t : t;
     177             : 
     178             :    // Use a process of exclusion to figure out
     179             :    // what kind of type we have, this relies on
     180             :    // IEEE conforming reals that will treat
     181             :    // Nan's as unordered.  Some compilers
     182             :    // don't do this once optimisations are
     183             :    // turned on, hence the check for nan's above.
     184             :    if(at <= (std::numeric_limits<T>::max)())
     185             :    {
     186             :       if(at >= (std::numeric_limits<T>::min)())
     187             :          return FP_NORMAL;
     188             :       return (at != 0) ? FP_SUBNORMAL : FP_ZERO;
     189             :    }
     190             :    else if(at > (std::numeric_limits<T>::max)())
     191             :       return FP_INFINITE;
     192             :    return FP_NAN;
     193             : }
     194             : 
     195             : template <class T>
     196             : inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<false>&)
     197             : {
     198             : #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     199             :    if(std::numeric_limits<T>::is_specialized)
     200             :       return fpclassify_imp(t, generic_tag<true>());
     201             : #endif
     202             :    //
     203             :    // An unknown type with no numeric_limits support,
     204             :    // so what are we supposed to do we do here?
     205             :    //
     206             :    BOOST_MATH_INSTRUMENT_VARIABLE(t);
     207             : 
     208             :    return t == 0 ? FP_ZERO : FP_NORMAL;
     209             : }
     210             : 
     211             : template<class T>
     212             : int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag)
     213             : {
     214             :    typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
     215             : 
     216             :    BOOST_MATH_INSTRUMENT_VARIABLE(x);
     217             : 
     218             :    BOOST_DEDUCED_TYPENAME traits::bits a;
     219             :    traits::get_bits(x,a);
     220             :    BOOST_MATH_INSTRUMENT_VARIABLE(a);
     221             :    a &= traits::exponent | traits::flag | traits::significand;
     222             :    BOOST_MATH_INSTRUMENT_VARIABLE((traits::exponent | traits::flag | traits::significand));
     223             :    BOOST_MATH_INSTRUMENT_VARIABLE(a);
     224             : 
     225             :    if(a <= traits::significand) {
     226             :       if(a == 0)
     227             :          return FP_ZERO;
     228             :       else
     229             :          return FP_SUBNORMAL;
     230             :    }
     231             : 
     232             :    if(a < traits::exponent) return FP_NORMAL;
     233             : 
     234             :    a &= traits::significand;
     235             :    if(a == 0) return FP_INFINITE;
     236             : 
     237             :    return FP_NAN;
     238             : }
     239             : 
     240             : template<class T>
     241             : int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
     242             : {
     243             :    typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
     244             : 
     245             :    BOOST_MATH_INSTRUMENT_VARIABLE(x);
     246             : 
     247             :    BOOST_DEDUCED_TYPENAME traits::bits a;
     248             :    traits::get_bits(x,a);
     249             :    a &= traits::exponent | traits::flag | traits::significand;
     250             : 
     251             :    if(a <= traits::significand) {
     252             :       if(x == 0)
     253             :          return FP_ZERO;
     254             :       else
     255             :          return FP_SUBNORMAL;
     256             :    }
     257             : 
     258             :    if(a < traits::exponent) return FP_NORMAL;
     259             : 
     260             :    a &= traits::significand;
     261             :    traits::set_bits(x,a);
     262             :    if(x == 0) return FP_INFINITE;
     263             : 
     264             :    return FP_NAN;
     265             : }
     266             : 
     267             : #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS))
     268             : inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
     269             : {
     270             :    return boost::math::detail::fpclassify_imp(t, generic_tag<true>());
     271             : }
     272             : #endif
     273             : 
     274             : }  // namespace detail
     275             : 
     276             : template <class T>
     277             : inline int fpclassify BOOST_NO_MACRO_EXPAND(T t)
     278             : {
     279             :    typedef typename detail::fp_traits<T>::type traits;
     280             :    typedef typename traits::method method;
     281             :    typedef typename tools::promote_args_permissive<T>::type value_type;
     282             : #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     283             :    if(std::numeric_limits<T>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
     284             :       return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
     285             :    return detail::fpclassify_imp(static_cast<value_type>(t), method());
     286             : #else
     287             :    return detail::fpclassify_imp(static_cast<value_type>(t), method());
     288             : #endif
     289             : }
     290             : 
     291             : #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     292             : template <>
     293             : inline int fpclassify<long double> BOOST_NO_MACRO_EXPAND(long double t)
     294             : {
     295             :    typedef detail::fp_traits<long double>::type traits;
     296             :    typedef traits::method method;
     297             :    typedef long double value_type;
     298             : #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     299             :    if(std::numeric_limits<long double>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(0)))
     300             :       return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
     301             :    return detail::fpclassify_imp(static_cast<value_type>(t), method());
     302             : #else
     303             :    return detail::fpclassify_imp(static_cast<value_type>(t), method());
     304             : #endif
     305             : }
     306             : #endif
     307             : 
     308             : namespace detail {
     309             : 
     310             : #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
     311             :     template<class T>
     312             :     inline bool isfinite_impl(T x, native_tag const&)
     313             :     {
     314             :         return (std::isfinite)(x);
     315             :     }
     316             : #endif
     317             : 
     318             :     template<class T>
     319             :     inline bool isfinite_impl(T x, generic_tag<true> const&)
     320             :     {
     321             :         return x >= -(std::numeric_limits<T>::max)()
     322             :             && x <= (std::numeric_limits<T>::max)();
     323             :     }
     324             : 
     325             :     template<class T>
     326             :     inline bool isfinite_impl(T x, generic_tag<false> const&)
     327             :     {
     328             : #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     329             :       if(std::numeric_limits<T>::is_specialized)
     330             :          return isfinite_impl(x, generic_tag<true>());
     331             : #endif
     332             :        (void)x; // warning suppression.
     333             :        return true;
     334             :     }
     335             : 
     336             :     template<class T>
     337             :     inline bool isfinite_impl(T x, ieee_tag const&)
     338             :     {
     339             :         typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
     340             :         BOOST_DEDUCED_TYPENAME traits::bits a;
     341             :         traits::get_bits(x,a);
     342             :         a &= traits::exponent;
     343             :         return a != traits::exponent;
     344             :     }
     345             : 
     346             : #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
     347             : inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
     348             : {
     349             :    return boost::math::detail::isfinite_impl(t, generic_tag<true>());
     350             : }
     351             : #endif
     352             : 
     353             : }
     354             : 
     355             : template<class T>
     356             : inline bool (isfinite)(T x)
     357             : { //!< \brief return true if floating-point type t is finite.
     358             :    typedef typename detail::fp_traits<T>::type traits;
     359             :    typedef typename traits::method method;
     360             :    // typedef typename boost::is_floating_point<T>::type fp_tag;
     361             :    typedef typename tools::promote_args_permissive<T>::type value_type;
     362             :    return detail::isfinite_impl(static_cast<value_type>(x), method());
     363             : }
     364             : 
     365             : #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     366             : template<>
     367             : inline bool (isfinite)(long double x)
     368             : { //!< \brief return true if floating-point type t is finite.
     369             :    typedef detail::fp_traits<long double>::type traits;
     370             :    typedef traits::method method;
     371             :    //typedef boost::is_floating_point<long double>::type fp_tag;
     372             :    typedef long double value_type;
     373             :    return detail::isfinite_impl(static_cast<value_type>(x), method());
     374             : }
     375             : #endif
     376             : 
     377             : //------------------------------------------------------------------------------
     378             : 
     379             : namespace detail {
     380             : 
     381             : #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
     382             :     template<class T>
     383             :     inline bool isnormal_impl(T x, native_tag const&)
     384             :     {
     385             :         return (std::isnormal)(x);
     386             :     }
     387             : #endif
     388             : 
     389             :     template<class T>
     390             :     inline bool isnormal_impl(T x, generic_tag<true> const&)
     391             :     {
     392             :         if(x < 0) x = -x;
     393             :         return x >= (std::numeric_limits<T>::min)()
     394             :             && x <= (std::numeric_limits<T>::max)();
     395             :     }
     396             : 
     397             :     template<class T>
     398             :     inline bool isnormal_impl(T x, generic_tag<false> const&)
     399             :     {
     400             : #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     401             :       if(std::numeric_limits<T>::is_specialized)
     402             :          return isnormal_impl(x, generic_tag<true>());
     403             : #endif
     404             :        return !(x == 0);
     405             :     }
     406             : 
     407             :     template<class T>
     408             :     inline bool isnormal_impl(T x, ieee_tag const&)
     409             :     {
     410             :         typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
     411             :         BOOST_DEDUCED_TYPENAME traits::bits a;
     412             :         traits::get_bits(x,a);
     413             :         a &= traits::exponent | traits::flag;
     414             :         return (a != 0) && (a < traits::exponent);
     415             :     }
     416             : 
     417             : #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
     418             : inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
     419             : {
     420             :    return boost::math::detail::isnormal_impl(t, generic_tag<true>());
     421             : }
     422             : #endif
     423             : 
     424             : }
     425             : 
     426             : template<class T>
     427             : inline bool (isnormal)(T x)
     428             : {
     429             :    typedef typename detail::fp_traits<T>::type traits;
     430             :    typedef typename traits::method method;
     431             :    //typedef typename boost::is_floating_point<T>::type fp_tag;
     432             :    typedef typename tools::promote_args_permissive<T>::type value_type;
     433             :    return detail::isnormal_impl(static_cast<value_type>(x), method());
     434             : }
     435             : 
     436             : #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     437             : template<>
     438             : inline bool (isnormal)(long double x)
     439             : {
     440             :    typedef detail::fp_traits<long double>::type traits;
     441             :    typedef traits::method method;
     442             :    //typedef boost::is_floating_point<long double>::type fp_tag;
     443             :    typedef long double value_type;
     444             :    return detail::isnormal_impl(static_cast<value_type>(x), method());
     445             : }
     446             : #endif
     447             : 
     448             : //------------------------------------------------------------------------------
     449             : 
     450             : namespace detail {
     451             : 
     452             : #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
     453             :     template<class T>
     454           0 :     inline bool isinf_impl(T x, native_tag const&)
     455             :     {
     456           0 :         return (std::isinf)(x);
     457             :     }
     458             : #endif
     459             : 
     460             :     template<class T>
     461             :     inline bool isinf_impl(T x, generic_tag<true> const&)
     462             :     {
     463             :         (void)x; // in case the compiler thinks that x is unused because std::numeric_limits<T>::has_infinity is false
     464             :         return std::numeric_limits<T>::has_infinity
     465             :             && ( x == std::numeric_limits<T>::infinity()
     466             :                  || x == -std::numeric_limits<T>::infinity());
     467             :     }
     468             : 
     469             :     template<class T>
     470             :     inline bool isinf_impl(T x, generic_tag<false> const&)
     471             :     {
     472             : #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     473             :       if(std::numeric_limits<T>::is_specialized)
     474             :          return isinf_impl(x, generic_tag<true>());
     475             : #endif
     476             :         (void)x; // warning suppression.
     477             :         return false;
     478             :     }
     479             : 
     480             :     template<class T>
     481             :     inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&)
     482             :     {
     483             :         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
     484             : 
     485             :         BOOST_DEDUCED_TYPENAME traits::bits a;
     486             :         traits::get_bits(x,a);
     487             :         a &= traits::exponent | traits::significand;
     488             :         return a == traits::exponent;
     489             :     }
     490             : 
     491             :     template<class T>
     492             :     inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&)
     493             :     {
     494             :         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
     495             : 
     496             :         BOOST_DEDUCED_TYPENAME traits::bits a;
     497             :         traits::get_bits(x,a);
     498             :         a &= traits::exponent | traits::significand;
     499             :         if(a != traits::exponent)
     500             :             return false;
     501             : 
     502             :         traits::set_bits(x,0);
     503             :         return x == 0;
     504             :     }
     505             : 
     506             : #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
     507             : inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
     508             : {
     509             :    return boost::math::detail::isinf_impl(t, generic_tag<true>());
     510             : }
     511             : #endif
     512             : 
     513             : }   // namespace detail
     514             : 
     515             : template<class T>
     516           0 : inline bool (isinf)(T x)
     517             : {
     518             :    typedef typename detail::fp_traits<T>::type traits;
     519             :    typedef typename traits::method method;
     520             :    // typedef typename boost::is_floating_point<T>::type fp_tag;
     521             :    typedef typename tools::promote_args_permissive<T>::type value_type;
     522           0 :    return detail::isinf_impl(static_cast<value_type>(x), method());
     523             : }
     524             : 
     525             : #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     526             : template<>
     527             : inline bool (isinf)(long double x)
     528             : {
     529             :    typedef detail::fp_traits<long double>::type traits;
     530             :    typedef traits::method method;
     531             :    //typedef boost::is_floating_point<long double>::type fp_tag;
     532             :    typedef long double value_type;
     533             :    return detail::isinf_impl(static_cast<value_type>(x), method());
     534             : }
     535             : #endif
     536             : #if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
     537             : template<>
     538             : inline bool (isinf)(__float128 x)
     539             : {
     540             :    return ::isinfq(x);
     541             : }
     542             : #endif
     543             : 
     544             : //------------------------------------------------------------------------------
     545             : 
     546             : namespace detail {
     547             : 
     548             : #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
     549             :     template<class T>
     550           0 :     inline bool isnan_impl(T x, native_tag const&)
     551             :     {
     552           0 :         return (std::isnan)(x);
     553             :     }
     554             : #endif
     555             : 
     556             :     template<class T>
     557             :     inline bool isnan_impl(T x, generic_tag<true> const&)
     558             :     {
     559             :         return std::numeric_limits<T>::has_infinity
     560             :             ? !(x <= std::numeric_limits<T>::infinity())
     561             :             : x != x;
     562             :     }
     563             : 
     564             :     template<class T>
     565             :     inline bool isnan_impl(T x, generic_tag<false> const&)
     566             :     {
     567             : #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     568             :       if(std::numeric_limits<T>::is_specialized)
     569             :          return isnan_impl(x, generic_tag<true>());
     570             : #endif
     571             :         (void)x; // warning suppression
     572             :         return false;
     573             :     }
     574             : 
     575             :     template<class T>
     576             :     inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&)
     577             :     {
     578             :         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
     579             : 
     580             :         BOOST_DEDUCED_TYPENAME traits::bits a;
     581             :         traits::get_bits(x,a);
     582             :         a &= traits::exponent | traits::significand;
     583             :         return a > traits::exponent;
     584             :     }
     585             : 
     586             :     template<class T>
     587             :     inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&)
     588             :     {
     589             :         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
     590             : 
     591             :         BOOST_DEDUCED_TYPENAME traits::bits a;
     592             :         traits::get_bits(x,a);
     593             : 
     594             :         a &= traits::exponent | traits::significand;
     595             :         if(a < traits::exponent)
     596             :             return false;
     597             : 
     598             :         a &= traits::significand;
     599             :         traits::set_bits(x,a);
     600             :         return x != 0;
     601             :     }
     602             : 
     603             : }   // namespace detail
     604             : 
     605             : template<class T>
     606           0 : inline bool (isnan)(T x)
     607             : { //!< \brief return true if floating-point type t is NaN (Not A Number).
     608             :    typedef typename detail::fp_traits<T>::type traits;
     609             :    typedef typename traits::method method;
     610             :    // typedef typename boost::is_floating_point<T>::type fp_tag;
     611           0 :    return detail::isnan_impl(x, method());
     612             : }
     613             : 
     614             : #ifdef isnan
     615             : template <> inline bool isnan BOOST_NO_MACRO_EXPAND<float>(float t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
     616             : template <> inline bool isnan BOOST_NO_MACRO_EXPAND<double>(double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
     617             : template <> inline bool isnan BOOST_NO_MACRO_EXPAND<long double>(long double t){ return ::boost::math_detail::is_nan_helper(t, boost::true_type()); }
     618             : #elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
     619             : template<>
     620             : inline bool (isnan)(long double x)
     621             : { //!< \brief return true if floating-point type t is NaN (Not A Number).
     622             :    typedef detail::fp_traits<long double>::type traits;
     623             :    typedef traits::method method;
     624             :    //typedef boost::is_floating_point<long double>::type fp_tag;
     625             :    return detail::isnan_impl(x, method());
     626             : }
     627             : #endif
     628             : #if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
     629             : template<>
     630             : inline bool (isnan)(__float128 x)
     631             : {
     632             :    return ::isnanq(x);
     633             : }
     634             : #endif
     635             : 
     636             : } // namespace math
     637             : } // namespace boost
     638             : 
     639             : #endif // BOOST_MATH_FPCLASSIFY_HPP
     640             : 

Generated by: LCOV version 1.14