-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Constexpr isfinite and isnormal (#674)
- Loading branch information
Showing
9 changed files
with
270 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// (C) Copyright Matt Borland 2021. | ||
// Use, modification and distribution are subject to the | ||
// Boost Software License, Version 1.0. (See accompanying file | ||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#ifndef BOOST_MATH_CCMATH_ISFINITE | ||
#define BOOST_MATH_CCMATH_ISFINITE | ||
|
||
#include <cmath> | ||
#include <type_traits> | ||
#include <boost/math/tools/is_constant_evaluated.hpp> | ||
#include <boost/math/ccmath/isinf.hpp> | ||
#include <boost/math/ccmath/isnan.hpp> | ||
|
||
namespace boost::math::ccmath { | ||
|
||
template <typename T> | ||
inline constexpr bool isfinite(T x) | ||
{ | ||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) | ||
{ | ||
// bool isfinite (IntegralType arg) is a set of overloads accepting the arg argument of any integral type | ||
// equivalent to casting the integral argument arg to double (e.g. static_cast<double>(arg)) | ||
if constexpr (std::is_integral_v<T>) | ||
{ | ||
return !boost::math::ccmath::isinf(static_cast<double>(x)) && !boost::math::ccmath::isnan(static_cast<double>(x)); | ||
} | ||
else | ||
{ | ||
return !boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(x); | ||
} | ||
} | ||
else | ||
{ | ||
using std::isfinite; | ||
|
||
if constexpr (!std::is_integral_v<T>) | ||
{ | ||
return isfinite(x); | ||
} | ||
else | ||
{ | ||
return isfinite(static_cast<double>(x)); | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
#endif // BOOST_MATH_CCMATH_ISFINITE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// (C) Copyright Matt Borland 2021. | ||
// Use, modification and distribution are subject to the | ||
// Boost Software License, Version 1.0. (See accompanying file | ||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#ifndef BOOST_MATH_ISNORMAL_HPP | ||
#define BOOST_MATH_ISNORMAL_HPP | ||
|
||
#include <cmath> | ||
#include <limits> | ||
#include <type_traits> | ||
#include <boost/math/tools/is_constant_evaluated.hpp> | ||
#include <boost/math/ccmath/abs.hpp> | ||
#include <boost/math/ccmath/isinf.hpp> | ||
#include <boost/math/ccmath/isnan.hpp> | ||
|
||
namespace boost::math::ccmath { | ||
|
||
template <typename T> | ||
inline constexpr bool isnormal(T x) | ||
{ | ||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) | ||
{ | ||
return x == T(0) ? false : | ||
boost::math::ccmath::isinf(x) ? false : | ||
boost::math::ccmath::isnan(x) ? false : | ||
boost::math::ccmath::abs(x) < (std::numeric_limits<T>::min)() ? false : true; | ||
} | ||
else | ||
{ | ||
using std::isnormal; | ||
|
||
if constexpr (!std::is_integral_v<T>) | ||
{ | ||
return isnormal(x); | ||
} | ||
else | ||
{ | ||
return isnormal(static_cast<double>(x)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
#endif // BOOST_MATH_ISNORMAL_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// (C) Copyright Matt Borland 2021. | ||
// Use, modification and distribution are subject to the | ||
// Boost Software License, Version 1.0. (See accompanying file | ||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#include <cmath> | ||
#include <cfloat> | ||
#include <cstdint> | ||
#include <limits> | ||
#include <type_traits> | ||
#include <boost/math/ccmath/isfinite.hpp> | ||
|
||
#ifdef BOOST_HAS_FLOAT128 | ||
#include <boost/multiprecision/float128.hpp> | ||
#endif | ||
|
||
template <typename T> | ||
void test() | ||
{ | ||
if constexpr (std::numeric_limits<T>::has_quiet_NaN) | ||
{ | ||
static_assert(!boost::math::ccmath::isfinite(std::numeric_limits<T>::quiet_NaN()), "Wrong response to NAN"); | ||
} | ||
|
||
static_assert(boost::math::ccmath::isfinite(T(0)), "Wrong response to 0"); | ||
|
||
if constexpr (!std::is_integral_v<T>) | ||
{ | ||
static_assert(boost::math::ccmath::isfinite((std::numeric_limits<T>::min)()/2), "Wrong response to subnormal"); | ||
static_assert(!boost::math::ccmath::isfinite(std::numeric_limits<T>::infinity()), "Wrong response to infinity"); | ||
} | ||
else | ||
{ | ||
// Integer types define infinity as 0 | ||
// https://en.cppreference.com/w/cpp/types/numeric_limits/infinity | ||
static_assert(boost::math::ccmath::isfinite(std::numeric_limits<T>::infinity()), "Wrong response to infinity"); | ||
} | ||
} | ||
|
||
#ifndef BOOST_MATH_NO_CONSTEXPR_DETECTION | ||
int main() | ||
{ | ||
test<float>(); | ||
test<double>(); | ||
|
||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
test<long double>(); | ||
#endif | ||
|
||
#if defined(BOOST_HAS_FLOAT128) && !defined(BOOST_MATH_USING_BUILTIN_CONSTANT_P) | ||
test<boost::multiprecision::float128>(); | ||
#endif | ||
|
||
test<int>(); | ||
test<unsigned>(); | ||
test<long>(); | ||
test<std::int32_t>(); | ||
test<std::int64_t>(); | ||
test<std::uint32_t>(); | ||
|
||
return 0; | ||
} | ||
#else | ||
int main() | ||
{ | ||
return 0; | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// (C) Copyright Matt Borland 2021. | ||
// Use, modification and distribution are subject to the | ||
// Boost Software License, Version 1.0. (See accompanying file | ||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#include <cmath> | ||
#include <cfloat> | ||
#include <cstdint> | ||
#include <limits> | ||
#include <type_traits> | ||
#include <boost/math/ccmath/isnormal.hpp> | ||
|
||
#ifdef BOOST_HAS_FLOAT128 | ||
#include <boost/multiprecision/float128.hpp> | ||
#endif | ||
|
||
// Determines if the given argument is normal, i.e. is neither zero, subnormal, infinite nor NaN. | ||
template <typename T> | ||
void test() | ||
{ | ||
if constexpr (std::numeric_limits<T>::has_quiet_NaN) | ||
{ | ||
static_assert(!boost::math::ccmath::isnormal(std::numeric_limits<T>::quiet_NaN()), "Wrong response to quiet NAN"); | ||
} | ||
|
||
static_assert(!boost::math::ccmath::isnormal(T(0)), "Wrong response to 0"); | ||
|
||
if constexpr (!std::is_integral_v<T>) | ||
{ | ||
static_assert(!boost::math::ccmath::isnormal((std::numeric_limits<T>::min)() / 2), "Wrong response to subnormal"); | ||
static_assert(!boost::math::ccmath::isnormal(std::numeric_limits<T>::infinity()), "Wrong response to infinity"); | ||
} | ||
|
||
static_assert(boost::math::ccmath::isnormal(T(1)), "Wrong response to normal number"); | ||
} | ||
|
||
#ifndef BOOST_MATH_NO_CONSTEXPR_DETECTION | ||
int main() | ||
{ | ||
test<float>(); | ||
test<double>(); | ||
|
||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
test<long double>(); | ||
#endif | ||
|
||
#if defined(BOOST_HAS_FLOAT128) && !defined(BOOST_MATH_USING_BUILTIN_CONSTANT_P) | ||
test<boost::multiprecision::float128>(); | ||
#endif | ||
|
||
test<int>(); | ||
test<unsigned>(); | ||
test<long>(); | ||
test<std::int32_t>(); | ||
test<std::int64_t>(); | ||
test<std::uint32_t>(); | ||
|
||
return 0; | ||
} | ||
#else | ||
int main() | ||
{ | ||
return 0; | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// (C) Copyright Matt Borland 2021. | ||
// Use, modification and distribution are subject to the | ||
// Boost Software License, Version 1.0. (See accompanying file | ||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#include <boost/math/ccmath/isfinite.hpp> | ||
#include "test_compile_result.hpp" | ||
|
||
void compile_and_link_test() | ||
{ | ||
check_result<bool>(boost::math::ccmath::isfinite(1.0f)); | ||
check_result<bool>(boost::math::ccmath::isfinite(1.0)); | ||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
check_result<bool>(boost::math::ccmath::isfinite(1.0l)); | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// (C) Copyright Matt Borland 2021. | ||
// Use, modification and distribution are subject to the | ||
// Boost Software License, Version 1.0. (See accompanying file | ||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
#include <boost/math/ccmath/isnormal.hpp> | ||
#include "test_compile_result.hpp" | ||
|
||
void compile_and_link_test() | ||
{ | ||
check_result<bool>(boost::math::ccmath::isnormal(1.0f)); | ||
check_result<bool>(boost::math::ccmath::isnormal(1.0)); | ||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
check_result<bool>(boost::math::ccmath::isnormal(1.0l)); | ||
#endif | ||
} |