2
0
mirror of https://github.com/boostorg/math.git synced 2026-01-19 04:22:09 +00:00

Merge pull request #432 from boostorg/improve_float_next

Update float_next/float_prior to handle types with exponents larger t…
This commit is contained in:
jzmaddock
2020-09-04 11:49:16 +01:00
committed by GitHub
2 changed files with 26 additions and 4 deletions

View File

@@ -16,6 +16,7 @@
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
#include <boost/math/special_functions/trunc.hpp>
#include <boost/math/tools/traits.hpp>
#include <float.h>
@@ -169,11 +170,25 @@ inline T get_min_shift_value()
return val;
}
template <class T, bool b = boost::math::tools::detail::has_backend_type<T>::value>
struct exponent_type
{
typedef int type;
};
template <class T>
struct exponent_type<T, true>
{
typedef typename T::backend_type::exponent_type type;
};
template <class T, class Policy>
T float_next_imp(const T& val, const boost::true_type&, const Policy& pol)
{
typedef typename exponent_type<T>::type exponent_type;
BOOST_MATH_STD_USING
int expon;
exponent_type expon;
static const char* function = "float_next<%1%>(%1%)";
int fpclass = (boost::math::fpclassify)(val);
@@ -216,11 +231,13 @@ T float_next_imp(const T& val, const boost::true_type&, const Policy& pol)
template <class T, class Policy>
T float_next_imp(const T& val, const boost::false_type&, const Policy& pol)
{
typedef typename exponent_type<T>::type exponent_type;
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
BOOST_MATH_STD_USING
boost::intmax_t expon;
exponent_type expon;
static const char* function = "float_next<%1%>(%1%)";
int fpclass = (boost::math::fpclassify)(val);
@@ -302,8 +319,10 @@ namespace detail{
template <class T, class Policy>
T float_prior_imp(const T& val, const boost::true_type&, const Policy& pol)
{
typedef typename exponent_type<T>::type exponent_type;
BOOST_MATH_STD_USING
int expon;
exponent_type expon;
static const char* function = "float_prior<%1%>(%1%)";
int fpclass = (boost::math::fpclassify)(val);
@@ -347,11 +366,13 @@ T float_prior_imp(const T& val, const boost::true_type&, const Policy& pol)
template <class T, class Policy>
T float_prior_imp(const T& val, const boost::false_type&, const Policy& pol)
{
typedef typename exponent_type<T>::type exponent_type;
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
BOOST_MATH_STD_USING
boost::intmax_t expon;
exponent_type expon;
static const char* function = "float_prior<%1%>(%1%)";
int fpclass = (boost::math::fpclassify)(val);

View File

@@ -34,6 +34,7 @@ namespace detail{
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_value_type, value_type, true)
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_policy_type, policy_type, true)
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_backend_type, backend_type, true)
template<class D>
char cdf(const D& ...);