forked from boostorg/math
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
292 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,57 @@ | ||
// (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_ILOGB_HPP | ||
#define BOOST_MATH_CCMATH_ILOGB_HPP | ||
|
||
#include <cmath> | ||
#include <type_traits> | ||
#include <boost/math/tools/is_constant_evaluated.hpp> | ||
#include <boost/math/ccmath/logb.hpp> | ||
#include <boost/math/ccmath/isinf.hpp> | ||
#include <boost/math/ccmath/isnan.hpp> | ||
#include <boost/math/ccmath/abs.hpp> | ||
|
||
namespace boost::math::ccmath { | ||
|
||
// If arg is not zero, infinite, or NaN, the value returned is exactly equivalent to static_cast<int>(std::logb(arg)) | ||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, bool> = true> | ||
inline constexpr int ilogb(Real arg) noexcept | ||
{ | ||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) | ||
{ | ||
return boost::math::ccmath::abs(arg) == Real(0) ? FP_ILOGB0 : | ||
boost::math::ccmath::isinf(arg) ? INT_MAX : | ||
boost::math::ccmath::isnan(arg) ? FP_ILOGBNAN : | ||
static_cast<int>(boost::math::ccmath::logb(arg)); | ||
} | ||
else | ||
{ | ||
using std::ilogb; | ||
return ilogb(arg); | ||
} | ||
} | ||
|
||
template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true> | ||
inline constexpr int ilogb(Z arg) noexcept | ||
{ | ||
return boost::math::ccmath::ilogb(static_cast<double>(arg)); | ||
} | ||
|
||
inline constexpr int ilogbf(float arg) noexcept | ||
{ | ||
return boost::math::ccmath::ilogb(arg); | ||
} | ||
|
||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
inline constexpr int ilogbl(long double arg) noexcept | ||
{ | ||
return boost::math::ccmath::ilogb(arg); | ||
} | ||
#endif | ||
|
||
} // Namespaces | ||
|
||
#endif // BOOST_MATH_CCMATH_ILOGB_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// (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_LOGB_HPP | ||
#define BOOST_MATH_CCMATH_LOGB_HPP | ||
|
||
#include <cmath> | ||
#include <limits> | ||
#include <type_traits> | ||
#include <boost/math/tools/is_constant_evaluated.hpp> | ||
#include <boost/math/ccmath/frexp.hpp> | ||
#include <boost/math/ccmath/isinf.hpp> | ||
#include <boost/math/ccmath/isnan.hpp> | ||
#include <boost/math/ccmath/abs.hpp> | ||
|
||
namespace boost::math::ccmath { | ||
|
||
namespace detail { | ||
|
||
// The value of the exponent returned by std::logb is always 1 less than the exponent returned by | ||
// std::frexp because of the different normalization requirements: for the exponent e returned by std::logb, | ||
// |arg*r^-e| is between 1 and r (typically between 1 and 2), but for the exponent e returned by std::frexp, | ||
// |arg*2^-e| is between 0.5 and 1. | ||
template <typename T> | ||
inline constexpr T logb_impl(T arg) noexcept | ||
{ | ||
int exp = 0; | ||
boost::math::ccmath::frexp(arg, &exp); | ||
|
||
return exp - 1; | ||
} | ||
|
||
} // Namespace detail | ||
|
||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, bool> = true> | ||
inline constexpr Real logb(Real arg) noexcept | ||
{ | ||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) | ||
{ | ||
return boost::math::ccmath::abs(arg) == Real(0) ? -std::numeric_limits<Real>::infinity() : | ||
boost::math::ccmath::isinf(arg) ? std::numeric_limits<Real>::infinity() : | ||
boost::math::ccmath::isnan(arg) ? std::numeric_limits<Real>::quiet_NaN() : | ||
boost::math::ccmath::detail::logb_impl(arg); | ||
} | ||
else | ||
{ | ||
using std::logb; | ||
return logb(arg); | ||
} | ||
} | ||
|
||
template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true> | ||
inline constexpr double logb(Z arg) noexcept | ||
{ | ||
return boost::math::ccmath::logb(static_cast<double>(arg)); | ||
} | ||
|
||
inline constexpr float logbf(float arg) noexcept | ||
{ | ||
return boost::math::ccmath::logb(arg); | ||
} | ||
|
||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
inline constexpr long double logbl(long double arg) noexcept | ||
{ | ||
return boost::math::ccmath::logb(arg); | ||
} | ||
#endif | ||
|
||
} // Namespaces | ||
|
||
#endif // BOOST_MATH_CCMATH_LOGB_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,56 @@ | ||
// (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/ilogb.hpp> | ||
#include <boost/math/ccmath/isnan.hpp> | ||
#include <boost/math/ccmath/isinf.hpp> | ||
|
||
#ifdef BOOST_HAS_FLOAT128 | ||
#include <boost/multiprecision/float128.hpp> | ||
#endif | ||
|
||
template <typename T> | ||
constexpr void test() | ||
{ | ||
if constexpr (std::numeric_limits<T>::has_quiet_NaN) | ||
{ | ||
static_assert(boost::math::ccmath::ilogb(std::numeric_limits<T>::quiet_NaN()) == FP_ILOGBNAN, "If arg is a NaN, FP_ILOGBNAN is returned."); | ||
} | ||
|
||
static_assert(boost::math::ccmath::ilogb(T(0)) == FP_ILOGB0, "If arg is zero, FP_ILOGB0 is returned"); | ||
static_assert(boost::math::ccmath::ilogb(std::numeric_limits<T>::infinity()) == INT_MAX, "If arg is infinite, INT_MAX is returned"); | ||
|
||
// 123.45 = 1.92891 * 2^6 | ||
constexpr int test_exp = boost::math::ccmath::ilogb(T(123.45)); | ||
static_assert(test_exp == 6); | ||
} | ||
|
||
#if !defined(BOOST_MATH_NO_CONSTEXPR_DETECTION) && !defined(BOOST_MATH_USING_BUILTIN_CONSTANT_P) | ||
int main() | ||
{ | ||
test<float>(); | ||
test<double>(); | ||
|
||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
test<long double>(); | ||
#endif | ||
|
||
#ifdef BOOST_HAS_FLOAT128 | ||
test<boost::multiprecision::float128>(); | ||
#endif | ||
|
||
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,60 @@ | ||
// (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/logb.hpp> | ||
#include <boost/math/ccmath/isnan.hpp> | ||
#include <boost/math/ccmath/isinf.hpp> | ||
|
||
#ifdef BOOST_HAS_FLOAT128 | ||
#include <boost/multiprecision/float128.hpp> | ||
#endif | ||
|
||
template <typename T> | ||
constexpr void test() | ||
{ | ||
if constexpr (std::numeric_limits<T>::has_quiet_NaN) | ||
{ | ||
static_assert(boost::math::ccmath::isnan(boost::math::ccmath::logb(std::numeric_limits<T>::quiet_NaN())), "if arg is NaN, NaN is returned"); | ||
} | ||
|
||
static_assert(boost::math::ccmath::isinf(boost::math::ccmath::logb(T(0))), "If arg is +-0, -infinity is returned"); | ||
static_assert(boost::math::ccmath::isinf(boost::math::ccmath::logb(T(-0))), "If arg is +-0, -infinity is returned"); | ||
static_assert(boost::math::ccmath::isinf(boost::math::ccmath::logb(std::numeric_limits<T>::infinity())), | ||
"if arg is +-infinity, infinity is returned"); | ||
static_assert(boost::math::ccmath::isinf(boost::math::ccmath::logb(-std::numeric_limits<T>::infinity())), | ||
"if arg is +-infinity, infinity is returned"); | ||
|
||
// 123.45 = 1.92891 * 2^6 | ||
constexpr T test_exp = boost::math::ccmath::logb(T(123.45)); | ||
static_assert(test_exp == T(6)); | ||
} | ||
|
||
#if !defined(BOOST_MATH_NO_CONSTEXPR_DETECTION) && !defined(BOOST_MATH_USING_BUILTIN_CONSTANT_P) | ||
int main() | ||
{ | ||
test<float>(); | ||
test<double>(); | ||
|
||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
test<long double>(); | ||
#endif | ||
|
||
#ifdef BOOST_HAS_FLOAT128 | ||
test<boost::multiprecision::float128>(); | ||
#endif | ||
|
||
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/ilogb.hpp> | ||
#include "test_compile_result.hpp" | ||
|
||
void compile_and_link_test() | ||
{ | ||
check_result<int>(boost::math::ccmath::ilogb(1.0f)); | ||
check_result<int>(boost::math::ccmath::ilogb(1.0)); | ||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
check_result<int>(boost::math::ccmath::ilogb(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/logb.hpp> | ||
#include "test_compile_result.hpp" | ||
|
||
void compile_and_link_test() | ||
{ | ||
check_result<float>(boost::math::ccmath::logb(1.0f)); | ||
check_result<double>(boost::math::ccmath::logb(1.0)); | ||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | ||
check_result<long double>(boost::math::ccmath::logb(1.0l)); | ||
#endif | ||
} |