mirror of
https://github.com/boostorg/math.git
synced 2025-05-11 21:33:52 +00:00
Correct float_next(+INF) and float_prior(-INF)
Fixes https://github.com/boostorg/math/issues/1132
This commit is contained in:
parent
d1d59cdd20
commit
f3e0cde514
@ -194,10 +194,14 @@ T float_next_imp(const T& val, const std::true_type&, const Policy& pol)
|
||||
|
||||
int fpclass = (boost::math::fpclassify)(val);
|
||||
|
||||
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
|
||||
if (fpclass == (int)FP_INFINITE)
|
||||
{
|
||||
if(val < 0)
|
||||
if (val < 0)
|
||||
return -tools::max_value<T>();
|
||||
return val; // +INF
|
||||
}
|
||||
else if (fpclass == (int)FP_NAN)
|
||||
{
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument must be finite, but got %1%", val, pol);
|
||||
@ -243,10 +247,14 @@ T float_next_imp(const T& val, const std::false_type&, const Policy& pol)
|
||||
|
||||
int fpclass = (boost::math::fpclassify)(val);
|
||||
|
||||
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
|
||||
if (fpclass == (int)FP_INFINITE)
|
||||
{
|
||||
if(val < 0)
|
||||
if (val < 0)
|
||||
return -tools::max_value<T>();
|
||||
return val; // +INF
|
||||
}
|
||||
else if (fpclass == (int)FP_NAN)
|
||||
{
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument must be finite, but got %1%", val, pol);
|
||||
@ -328,10 +336,14 @@ T float_prior_imp(const T& val, const std::true_type&, const Policy& pol)
|
||||
|
||||
int fpclass = (boost::math::fpclassify)(val);
|
||||
|
||||
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
|
||||
if (fpclass == (int)FP_INFINITE)
|
||||
{
|
||||
if(val > 0)
|
||||
if (val > 0)
|
||||
return tools::max_value<T>();
|
||||
return val; // -INF
|
||||
}
|
||||
else if (fpclass == (int)FP_NAN)
|
||||
{
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument must be finite, but got %1%", val, pol);
|
||||
@ -378,10 +390,14 @@ T float_prior_imp(const T& val, const std::false_type&, const Policy& pol)
|
||||
|
||||
int fpclass = (boost::math::fpclassify)(val);
|
||||
|
||||
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
|
||||
if (fpclass == (int)FP_INFINITE)
|
||||
{
|
||||
if(val > 0)
|
||||
if (val > 0)
|
||||
return tools::max_value<T>();
|
||||
return val; // -INF
|
||||
}
|
||||
else if (fpclass == (int)FP_NAN)
|
||||
{
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument must be finite, but got %1%", val, pol);
|
||||
|
@ -171,12 +171,12 @@ void test_values(const T& val, const char* name)
|
||||
BOOST_CHECK_EQUAL(boost::math::float_advance(val, primes[i]), v1);
|
||||
BOOST_CHECK_EQUAL(boost::math::float_advance(val, -primes[i]), v2);
|
||||
}
|
||||
if(std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_infinity))
|
||||
BOOST_IF_CONSTEXPR(std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_infinity))
|
||||
{
|
||||
BOOST_CHECK_EQUAL(boost::math::float_prior(std::numeric_limits<T>::infinity()), (std::numeric_limits<T>::max)());
|
||||
BOOST_CHECK_EQUAL(boost::math::float_next(-std::numeric_limits<T>::infinity()), -(std::numeric_limits<T>::max)());
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_prior(-std::numeric_limits<T>::infinity()), std::domain_error);
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_next(std::numeric_limits<T>::infinity()), std::domain_error);
|
||||
BOOST_CHECK_EQUAL(boost::math::float_prior(-std::numeric_limits<T>::infinity()), -std::numeric_limits<T>::infinity());
|
||||
BOOST_CHECK_EQUAL(boost::math::float_next(std::numeric_limits<T>::infinity()), std::numeric_limits<T>::infinity());
|
||||
if(boost::math::policies:: BOOST_MATH_OVERFLOW_ERROR_POLICY == boost::math::policies::throw_on_error)
|
||||
{
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_prior(-(std::numeric_limits<T>::max)()), std::overflow_error);
|
||||
@ -188,6 +188,11 @@ void test_values(const T& val, const char* name)
|
||||
BOOST_CHECK_EQUAL(boost::math::float_next((std::numeric_limits<T>::max)()), std::numeric_limits<T>::infinity());
|
||||
}
|
||||
}
|
||||
BOOST_IF_CONSTEXPR(std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_quiet_NaN))
|
||||
{
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_prior((std::numeric_limits<T>::quiet_NaN)()), std::domain_error);
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_next((std::numeric_limits<T>::quiet_NaN)()), std::domain_error);
|
||||
}
|
||||
//
|
||||
// We need to test float_distance over multiple orders of magnitude,
|
||||
// the only way to get an accurate true result is to count the representations
|
||||
|
Loading…
x
Reference in New Issue
Block a user