File indexing completed on 2025-09-15 08:40:12
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MATH_FPCLASSIFY_HPP
0009 #define BOOST_MATH_FPCLASSIFY_HPP
0010
0011 #ifdef _MSC_VER
0012 #pragma once
0013 #endif
0014
0015 #include <boost/math/tools/config.hpp>
0016
0017 #ifndef BOOST_MATH_HAS_NVRTC
0018
0019 #include <boost/math/tools/real_cast.hpp>
0020 #include <boost/math/special_functions/math_fwd.hpp>
0021 #include <boost/math/special_functions/detail/fp_traits.hpp>
0022 #include <limits>
0023 #include <type_traits>
0024 #include <cmath>
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 #ifdef BOOST_MATH_HAS_GPU_SUPPORT
0086
0087 namespace boost { namespace math {
0088
0089 template<> inline BOOST_MATH_GPU_ENABLED bool (isnan)(float x) { return x != x; }
0090 template<> inline BOOST_MATH_GPU_ENABLED bool (isnan)(double x) { return x != x; }
0091
0092 template<> inline BOOST_MATH_GPU_ENABLED bool (isinf)(float x) { return x > FLT_MAX || x < -FLT_MAX; }
0093 template<> inline BOOST_MATH_GPU_ENABLED bool (isinf)(double x) { return x > DBL_MAX || x < -DBL_MAX; }
0094
0095 template<> inline BOOST_MATH_GPU_ENABLED bool (isfinite)(float x) { return !isnan(x) && !isinf(x); }
0096 template<> inline BOOST_MATH_GPU_ENABLED bool (isfinite)(double x) { return !isnan(x) && !isinf(x); }
0097
0098 template<> inline BOOST_MATH_GPU_ENABLED bool (isnormal)(float x)
0099 {
0100 if(x < 0) x = -x;
0101 return (x >= FLT_MIN) && (x <= FLT_MAX);
0102 }
0103 template<> inline BOOST_MATH_GPU_ENABLED bool (isnormal)(double x)
0104 {
0105 if(x < 0) x = -x;
0106 return (x >= DBL_MIN) && (x <= DBL_MAX);
0107 }
0108
0109 template<> inline BOOST_MATH_GPU_ENABLED int (fpclassify)(float t)
0110 {
0111 if((boost::math::isnan)(t))
0112 return FP_NAN;
0113
0114 float at = (t < 0.0f) ? -t : t;
0115
0116
0117
0118
0119
0120
0121
0122 if(at <= FLT_MAX)
0123 {
0124 if(at >= FLT_MIN)
0125 return FP_NORMAL;
0126 return (at != 0) ? FP_SUBNORMAL : FP_ZERO;
0127 }
0128 else if(at > FLT_MAX)
0129 return FP_INFINITE;
0130 return FP_NAN;
0131 }
0132
0133 template<> inline BOOST_MATH_GPU_ENABLED int (fpclassify)(double t)
0134 {
0135 if((boost::math::isnan)(t))
0136 return FP_NAN;
0137
0138 double at = (t < 0.0) ? -t : t;
0139
0140
0141
0142
0143
0144
0145
0146 if(at <= DBL_MAX)
0147 {
0148 if(at >= DBL_MIN)
0149 return FP_NORMAL;
0150 return (at != 0) ? FP_SUBNORMAL : FP_ZERO;
0151 }
0152 else if(at > DBL_MAX)
0153 return FP_INFINITE;
0154 return FP_NAN;
0155 }
0156
0157 #else
0158
0159 #if defined(_MSC_VER) || defined(BOOST_BORLANDC)
0160 #include <cfloat>
0161 #endif
0162 #ifdef BOOST_MATH_USE_FLOAT128
0163 #ifdef __has_include
0164 #if __has_include("quadmath.h")
0165 #include "quadmath.h"
0166 #define BOOST_MATH_HAS_QUADMATH_H
0167 #endif
0168 #endif
0169 #endif
0170
0171 #ifdef BOOST_NO_STDC_NAMESPACE
0172 namespace std{ using ::abs; using ::fabs; }
0173 #endif
0174
0175 namespace boost{
0176
0177
0178
0179
0180
0181
0182 namespace math_detail{
0183
0184 #ifdef _MSC_VER
0185 #pragma warning(push)
0186 #pragma warning(disable:4800)
0187 #endif
0188
0189 template <class T>
0190 inline bool is_nan_helper(T t, const std::true_type&)
0191 {
0192 #ifdef isnan
0193 return isnan(t);
0194 #elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY)
0195 (void)t;
0196 return false;
0197 #else
0198 return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN);
0199 #endif
0200 }
0201
0202 #ifdef _MSC_VER
0203 #pragma warning(pop)
0204 #endif
0205
0206 template <class T>
0207 inline bool is_nan_helper(T, const std::false_type&)
0208 {
0209 return false;
0210 }
0211 #if defined(BOOST_MATH_USE_FLOAT128)
0212 #if defined(BOOST_MATH_HAS_QUADMATH_H)
0213 inline bool is_nan_helper(__float128 f, const std::true_type&) { return ::isnanq(f); }
0214 inline bool is_nan_helper(__float128 f, const std::false_type&) { return ::isnanq(f); }
0215 #elif defined(BOOST_GNU_STDLIB) && BOOST_GNU_STDLIB && \
0216 _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
0217 inline bool is_nan_helper(__float128 f, const std::true_type&) { return std::isnan(static_cast<double>(f)); }
0218 inline bool is_nan_helper(__float128 f, const std::false_type&) { return std::isnan(static_cast<double>(f)); }
0219 #else
0220 inline bool is_nan_helper(__float128 f, const std::true_type&) { return boost::math::isnan(static_cast<double>(f)); }
0221 inline bool is_nan_helper(__float128 f, const std::false_type&) { return boost::math::isnan(static_cast<double>(f)); }
0222 #endif
0223 #endif
0224 }
0225
0226 namespace math{
0227
0228 namespace detail{
0229
0230 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0231 template <class T>
0232 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const native_tag&)
0233 {
0234 return (std::fpclassify)(t);
0235 }
0236 #endif
0237
0238 template <class T>
0239 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<true>&)
0240 {
0241 BOOST_MATH_INSTRUMENT_VARIABLE(t);
0242
0243
0244 #if defined(BOOST_HAS_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
0245 if(::boost::math_detail::is_nan_helper(t, typename std::is_floating_point<T>::type()))
0246 return FP_NAN;
0247 #elif defined(isnan)
0248 if(boost::math_detail::is_nan_helper(t, typename std::is_floating_point<T>::type()))
0249 return FP_NAN;
0250 #elif defined(_MSC_VER) || defined(BOOST_BORLANDC)
0251 if(::_isnan(boost::math::tools::real_cast<double>(t)))
0252 return FP_NAN;
0253 #endif
0254
0255 T at = (t < T(0)) ? -t : t;
0256
0257
0258
0259
0260
0261
0262
0263 if(at <= (std::numeric_limits<T>::max)())
0264 {
0265 if(at >= (std::numeric_limits<T>::min)())
0266 return FP_NORMAL;
0267 return (at != 0) ? FP_SUBNORMAL : FP_ZERO;
0268 }
0269 else if(at > (std::numeric_limits<T>::max)())
0270 return FP_INFINITE;
0271 return FP_NAN;
0272 }
0273
0274 template <class T>
0275 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag<false>&)
0276 {
0277 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0278 if(std::numeric_limits<T>::is_specialized)
0279 return fpclassify_imp(t, generic_tag<true>());
0280 #endif
0281
0282
0283
0284
0285 BOOST_MATH_INSTRUMENT_VARIABLE(t);
0286
0287 return t == 0 ? FP_ZERO : FP_NORMAL;
0288 }
0289
0290 template<class T>
0291 int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag)
0292 {
0293 typedef typename fp_traits<T>::type traits;
0294
0295 BOOST_MATH_INSTRUMENT_VARIABLE(x);
0296
0297 typename traits::bits a;
0298 traits::get_bits(x,a);
0299 BOOST_MATH_INSTRUMENT_VARIABLE(a);
0300 a &= traits::exponent | traits::flag | traits::significand;
0301 BOOST_MATH_INSTRUMENT_VARIABLE((traits::exponent | traits::flag | traits::significand));
0302 BOOST_MATH_INSTRUMENT_VARIABLE(a);
0303
0304 if(a <= traits::significand) {
0305 if(a == 0)
0306 return FP_ZERO;
0307 else
0308 return FP_SUBNORMAL;
0309 }
0310
0311 if(a < traits::exponent) return FP_NORMAL;
0312
0313 a &= traits::significand;
0314 if(a == 0) return FP_INFINITE;
0315
0316 return FP_NAN;
0317 }
0318
0319 template<class T>
0320 int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag)
0321 {
0322 typedef typename fp_traits<T>::type traits;
0323
0324 BOOST_MATH_INSTRUMENT_VARIABLE(x);
0325
0326 typename traits::bits a;
0327 traits::get_bits(x,a);
0328 a &= traits::exponent | traits::flag | traits::significand;
0329
0330 if(a <= traits::significand) {
0331 if(x == 0)
0332 return FP_ZERO;
0333 else
0334 return FP_SUBNORMAL;
0335 }
0336
0337 if(a < traits::exponent) return FP_NORMAL;
0338
0339 a &= traits::significand;
0340 traits::set_bits(x,a);
0341 if(x == 0) return FP_INFINITE;
0342
0343 return FP_NAN;
0344 }
0345
0346 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS))
0347 inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0348 {
0349 return boost::math::detail::fpclassify_imp(t, generic_tag<true>());
0350 }
0351 #endif
0352
0353 }
0354
0355 template <class T>
0356 inline int fpclassify BOOST_NO_MACRO_EXPAND(T t)
0357 {
0358 typedef typename detail::fp_traits<T>::type traits;
0359 typedef typename traits::method method;
0360 typedef typename tools::promote_args_permissive<T>::type value_type;
0361 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0362 if(std::numeric_limits<T>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(nullptr)))
0363 return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
0364 return detail::fpclassify_imp(static_cast<value_type>(t), method());
0365 #else
0366 return detail::fpclassify_imp(static_cast<value_type>(t), method());
0367 #endif
0368 }
0369
0370 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0371 template <>
0372 inline int fpclassify<long double> BOOST_NO_MACRO_EXPAND(long double t)
0373 {
0374 typedef detail::fp_traits<long double>::type traits;
0375 typedef traits::method method;
0376 typedef long double value_type;
0377 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0378 if(std::numeric_limits<long double>::is_specialized && detail::is_generic_tag_false(static_cast<method*>(nullptr)))
0379 return detail::fpclassify_imp(static_cast<value_type>(t), detail::generic_tag<true>());
0380 return detail::fpclassify_imp(static_cast<value_type>(t), method());
0381 #else
0382 return detail::fpclassify_imp(static_cast<value_type>(t), method());
0383 #endif
0384 }
0385 #endif
0386
0387 namespace detail {
0388
0389 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0390 template<class T>
0391 inline bool isfinite_impl(T x, native_tag const&)
0392 {
0393 return (std::isfinite)(x);
0394 }
0395 #endif
0396
0397 template<class T>
0398 inline bool isfinite_impl(T x, generic_tag<true> const&)
0399 {
0400 return x >= -(std::numeric_limits<T>::max)()
0401 && x <= (std::numeric_limits<T>::max)();
0402 }
0403
0404 template<class T>
0405 inline bool isfinite_impl(T x, generic_tag<false> const&)
0406 {
0407 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0408 if(std::numeric_limits<T>::is_specialized)
0409 return isfinite_impl(x, generic_tag<true>());
0410 #endif
0411 (void)x;
0412 return true;
0413 }
0414
0415 template<class T>
0416 inline bool isfinite_impl(T x, ieee_tag const&)
0417 {
0418 typedef typename detail::fp_traits<T>::type traits;
0419 typename traits::bits a;
0420 traits::get_bits(x,a);
0421 a &= traits::exponent;
0422 return a != traits::exponent;
0423 }
0424
0425 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
0426 inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0427 {
0428 return boost::math::detail::isfinite_impl(t, generic_tag<true>());
0429 }
0430 #endif
0431
0432 }
0433
0434 template<class T>
0435 inline bool (isfinite)(T x)
0436 {
0437 typedef typename detail::fp_traits<T>::type traits;
0438 typedef typename traits::method method;
0439
0440 typedef typename tools::promote_args_permissive<T>::type value_type;
0441 return detail::isfinite_impl(static_cast<value_type>(x), method());
0442 }
0443
0444 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0445 template<>
0446 inline bool (isfinite)(long double x)
0447 {
0448 typedef detail::fp_traits<long double>::type traits;
0449 typedef traits::method method;
0450
0451 typedef long double value_type;
0452 return detail::isfinite_impl(static_cast<value_type>(x), method());
0453 }
0454 #endif
0455
0456
0457
0458 namespace detail {
0459
0460 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0461 template<class T>
0462 inline bool isnormal_impl(T x, native_tag const&)
0463 {
0464 return (std::isnormal)(x);
0465 }
0466 #endif
0467
0468 template<class T>
0469 inline bool isnormal_impl(T x, generic_tag<true> const&)
0470 {
0471 if(x < 0) x = -x;
0472 return x >= (std::numeric_limits<T>::min)()
0473 && x <= (std::numeric_limits<T>::max)();
0474 }
0475
0476 template<class T>
0477 inline bool isnormal_impl(T x, generic_tag<false> const&)
0478 {
0479 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0480 if(std::numeric_limits<T>::is_specialized)
0481 return isnormal_impl(x, generic_tag<true>());
0482 #endif
0483 return !(x == 0);
0484 }
0485
0486 template<class T>
0487 inline bool isnormal_impl(T x, ieee_tag const&)
0488 {
0489 typedef typename detail::fp_traits<T>::type traits;
0490 typename traits::bits a;
0491 traits::get_bits(x,a);
0492 a &= traits::exponent | traits::flag;
0493 return (a != 0) && (a < traits::exponent);
0494 }
0495
0496 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
0497 inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0498 {
0499 return boost::math::detail::isnormal_impl(t, generic_tag<true>());
0500 }
0501 #endif
0502
0503 }
0504
0505 template<class T>
0506 inline bool (isnormal)(T x)
0507 {
0508 typedef typename detail::fp_traits<T>::type traits;
0509 typedef typename traits::method method;
0510
0511 typedef typename tools::promote_args_permissive<T>::type value_type;
0512 return detail::isnormal_impl(static_cast<value_type>(x), method());
0513 }
0514
0515 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0516 template<>
0517 inline bool (isnormal)(long double x)
0518 {
0519 typedef detail::fp_traits<long double>::type traits;
0520 typedef traits::method method;
0521
0522 typedef long double value_type;
0523 return detail::isnormal_impl(static_cast<value_type>(x), method());
0524 }
0525 #endif
0526
0527
0528
0529 namespace detail {
0530
0531 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0532 template<class T>
0533 inline bool isinf_impl(T x, native_tag const&)
0534 {
0535 return (std::isinf)(x);
0536 }
0537 #endif
0538
0539 template<class T>
0540 inline bool isinf_impl(T x, generic_tag<true> const&)
0541 {
0542 (void)x;
0543 return std::numeric_limits<T>::has_infinity
0544 && ( x == std::numeric_limits<T>::infinity()
0545 || x == -std::numeric_limits<T>::infinity());
0546 }
0547
0548 template<class T>
0549 inline bool isinf_impl(T x, generic_tag<false> const&)
0550 {
0551 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0552 if(std::numeric_limits<T>::is_specialized)
0553 return isinf_impl(x, generic_tag<true>());
0554 #endif
0555 (void)x;
0556 return false;
0557 }
0558
0559 template<class T>
0560 inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&)
0561 {
0562 typedef typename fp_traits<T>::type traits;
0563
0564 typename traits::bits a;
0565 traits::get_bits(x,a);
0566 a &= traits::exponent | traits::significand;
0567 return a == traits::exponent;
0568 }
0569
0570 template<class T>
0571 inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&)
0572 {
0573 typedef typename fp_traits<T>::type traits;
0574
0575 typename traits::bits a;
0576 traits::get_bits(x,a);
0577 a &= traits::exponent | traits::significand;
0578 if(a != traits::exponent)
0579 return false;
0580
0581 traits::set_bits(x,0);
0582 return x == 0;
0583 }
0584
0585 #if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY)
0586 inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&)
0587 {
0588 return boost::math::detail::isinf_impl(t, generic_tag<true>());
0589 }
0590 #endif
0591
0592 }
0593
0594 template<class T>
0595 inline bool (isinf)(T x)
0596 {
0597 typedef typename detail::fp_traits<T>::type traits;
0598 typedef typename traits::method method;
0599
0600 typedef typename tools::promote_args_permissive<T>::type value_type;
0601 return detail::isinf_impl(static_cast<value_type>(x), method());
0602 }
0603
0604 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
0605 template<>
0606 inline bool (isinf)(long double x)
0607 {
0608 typedef detail::fp_traits<long double>::type traits;
0609 typedef traits::method method;
0610
0611 typedef long double value_type;
0612 return detail::isinf_impl(static_cast<value_type>(x), method());
0613 }
0614 #endif
0615 #if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
0616 template<>
0617 inline bool (isinf)(__float128 x)
0618 {
0619 return ::isinfq(x);
0620 }
0621 #endif
0622
0623
0624
0625 namespace detail {
0626
0627 #ifdef BOOST_MATH_USE_STD_FPCLASSIFY
0628 template<class T>
0629 inline bool isnan_impl(T x, native_tag const&)
0630 {
0631 return (std::isnan)(x);
0632 }
0633 #endif
0634
0635 template<class T>
0636 inline bool isnan_impl(T x, generic_tag<true> const&)
0637 {
0638 return std::numeric_limits<T>::has_infinity
0639 ? !(x <= std::numeric_limits<T>::infinity())
0640 : x != x;
0641 }
0642
0643 template<class T>
0644 inline bool isnan_impl(T x, generic_tag<false> const&)
0645 {
0646 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
0647 if(std::numeric_limits<T>::is_specialized)
0648 return isnan_impl(x, generic_tag<true>());
0649 #endif
0650 (void)x;
0651 return false;
0652 }
0653
0654 template<class T>
0655 inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&)
0656 {
0657 typedef typename fp_traits<T>::type traits;
0658
0659 typename traits::bits a;
0660 traits::get_bits(x,a);
0661 a &= traits::exponent | traits::significand;
0662 return a > traits::exponent;
0663 }
0664
0665 template<class T>
0666 inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&)
0667 {
0668 typedef typename fp_traits<T>::type traits;
0669
0670 typename traits::bits a;
0671 traits::get_bits(x,a);
0672
0673 a &= traits::exponent | traits::significand;
0674 if(a < traits::exponent)
0675 return false;
0676
0677 a &= traits::significand;
0678 traits::set_bits(x,a);
0679 return x != 0;
0680 }
0681
0682 }
0683
0684 template<class T>
0685 inline bool (isnan)(T x)
0686 {
0687 typedef typename detail::fp_traits<T>::type traits;
0688 typedef typename traits::method method;
0689
0690 return detail::isnan_impl(x, method());
0691 }
0692
0693 #ifdef isnan
0694 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<float>(float t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); }
0695 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<double>(double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); }
0696 template <> inline bool isnan BOOST_NO_MACRO_EXPAND<long double>(long double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); }
0697 #elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
0698 template<>
0699 inline bool (isnan)(long double x)
0700 {
0701 typedef detail::fp_traits<long double>::type traits;
0702 typedef traits::method method;
0703
0704 return detail::isnan_impl(x, method());
0705 }
0706 #endif
0707 #if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H)
0708 template<>
0709 inline bool (isnan)(__float128 x)
0710 {
0711 return ::isnanq(x);
0712 }
0713 #endif
0714
0715 #endif
0716
0717 }
0718 }
0719
0720 #else
0721
0722 #include <boost/math/tools/type_traits.hpp>
0723
0724 namespace boost {
0725 namespace math {
0726
0727 template <typename T, boost::math::enable_if_t<boost::math::is_integral_v<T>, bool> = true>
0728 inline BOOST_MATH_GPU_ENABLED bool isnan(T x)
0729 {
0730 return false;
0731 }
0732
0733 template <typename T, boost::math::enable_if_t<!boost::math::is_integral_v<T>, bool> = true>
0734 inline BOOST_MATH_GPU_ENABLED bool isnan(T x)
0735 {
0736 return ::isnan(x);
0737 }
0738
0739 template <typename T, boost::math::enable_if_t<boost::math::is_integral_v<T>, bool> = true>
0740 inline BOOST_MATH_GPU_ENABLED bool isinf(T x)
0741 {
0742 return false;
0743 }
0744
0745 template <typename T, boost::math::enable_if_t<!boost::math::is_integral_v<T>, bool> = true>
0746 inline BOOST_MATH_GPU_ENABLED bool isinf(T x)
0747 {
0748 return ::isinf(x);
0749 }
0750
0751 template <typename T, boost::math::enable_if_t<boost::math::is_integral_v<T>, bool> = true>
0752 inline BOOST_MATH_GPU_ENABLED bool isfinite(T x)
0753 {
0754 return true;
0755 }
0756
0757 template <typename T, boost::math::enable_if_t<!boost::math::is_integral_v<T>, bool> = true>
0758 inline BOOST_MATH_GPU_ENABLED bool isfinite(T x)
0759 {
0760 return ::isfinite(x);
0761 }
0762
0763 template <typename T>
0764 inline BOOST_MATH_GPU_ENABLED bool isnormal(T x)
0765 {
0766 return x != static_cast<T>(0) && x != static_cast<T>(-0) &&
0767 !boost::math::isnan(x) &&
0768 !boost::math::isinf(x);
0769 }
0770
0771
0772 template <typename T>
0773 inline BOOST_MATH_GPU_ENABLED int fpclassify(T x)
0774 {
0775 if (boost::math::isnan(x))
0776 {
0777 return BOOST_MATH_FP_NAN;
0778 }
0779 else if (boost::math::isinf(x))
0780 {
0781 return BOOST_MATH_FP_INFINITE;
0782 }
0783 else if (x == static_cast<T>(0) || x == static_cast<T>(-0))
0784 {
0785 return BOOST_MATH_FP_ZERO;
0786 }
0787
0788 return BOOST_MATH_FP_NORMAL;
0789 }
0790
0791 }
0792 }
0793
0794 #endif
0795
0796 #endif
0797