mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Coverage: Improve next.hpp.
This commit is contained in:
@@ -469,13 +469,9 @@ T float_distance_imp(const T& a, const T& b, const std::true_type&, const Policy
|
||||
//
|
||||
static const char* function = "float_distance<%1%>(%1%, %1%)";
|
||||
if(!(boost::math::isfinite)(a))
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument a must be finite, but got %1%", a, pol);
|
||||
return policies::raise_domain_error<T>(function, "Argument a must be finite, but got %1%", a, pol);
|
||||
if(!(boost::math::isfinite)(b))
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument b must be finite, but got %1%", b, pol);
|
||||
return policies::raise_domain_error<T>(function, "Argument b must be finite, but got %1%", b, pol);
|
||||
//
|
||||
// Special cases:
|
||||
//
|
||||
@@ -577,13 +573,9 @@ T float_distance_imp(const T& a, const T& b, const std::false_type&, const Polic
|
||||
//
|
||||
static const char* function = "float_distance<%1%>(%1%, %1%)";
|
||||
if(!(boost::math::isfinite)(a))
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument a must be finite, but got %1%", a, pol);
|
||||
return policies::raise_domain_error<T>(function, "Argument a must be finite, but got %1%", a, pol);
|
||||
if(!(boost::math::isfinite)(b))
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument b must be finite, but got %1%", b, pol);
|
||||
return policies::raise_domain_error<T>(function, "Argument b must be finite, but got %1%", b, pol);
|
||||
//
|
||||
// Special cases:
|
||||
//
|
||||
@@ -726,9 +718,7 @@ T float_advance_imp(T val, int distance, const std::true_type&, const Policy& po
|
||||
int fpclass = (boost::math::fpclassify)(val);
|
||||
|
||||
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument val must be finite, but got %1%", val, pol);
|
||||
return policies::raise_domain_error<T>(function, "Argument val must be finite, but got %1%", val, pol);
|
||||
|
||||
if(val < 0)
|
||||
return -float_advance(-val, -distance, pol);
|
||||
@@ -760,10 +750,8 @@ T float_advance_imp(T val, int distance, const std::true_type&, const Policy& po
|
||||
int expon;
|
||||
(void)frexp(val, &expon);
|
||||
T limit = ldexp((distance < 0 ? T(0.5f) : T(1)), expon);
|
||||
if(val <= tools::min_value<T>())
|
||||
{
|
||||
limit = sign(T(distance)) * tools::min_value<T>();
|
||||
}
|
||||
// We can not have denorms here, since we have taken care of them above:
|
||||
BOOST_MATH_ASSERT(val > tools::min_value<T>());
|
||||
T limit_distance = float_distance(val, limit);
|
||||
while(fabs(limit_distance) < abs(distance))
|
||||
{
|
||||
@@ -782,7 +770,7 @@ T float_advance_imp(T val, int distance, const std::true_type&, const Policy& po
|
||||
limit_distance = float_distance(val, limit);
|
||||
if(distance && (limit_distance == 0))
|
||||
{
|
||||
return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol);
|
||||
return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); // LCOV_EXCL_LINE This *should* be unreachable.
|
||||
}
|
||||
}
|
||||
if((0.5f == frexp(val, &expon)) && (distance < 0))
|
||||
@@ -791,7 +779,7 @@ T float_advance_imp(T val, int distance, const std::true_type&, const Policy& po
|
||||
if(val != 0)
|
||||
diff = distance * ldexp(T(1), expon - tools::digits<T>());
|
||||
if(diff == 0)
|
||||
diff = distance * detail::get_smallest_value<T>();
|
||||
diff = distance * detail::get_smallest_value<T>(); // LCOV_EXCL_LINE This *should* be unreachable given that denorms are handled above already.
|
||||
return val += diff;
|
||||
} // float_advance_imp
|
||||
//
|
||||
@@ -812,9 +800,7 @@ T float_advance_imp(T val, int distance, const std::false_type&, const Policy& p
|
||||
int fpclass = (boost::math::fpclassify)(val);
|
||||
|
||||
if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
|
||||
return policies::raise_domain_error<T>(
|
||||
function,
|
||||
"Argument val must be finite, but got %1%", val, pol);
|
||||
return policies::raise_domain_error<T>(function, "Argument val must be finite, but got %1%", val, pol);
|
||||
|
||||
if(val < 0)
|
||||
return -float_advance(-val, -distance, pol);
|
||||
@@ -845,10 +831,7 @@ T float_advance_imp(T val, int distance, const std::false_type&, const Policy& p
|
||||
|
||||
std::intmax_t expon = 1 + ilogb(val);
|
||||
T limit = scalbn(T(1), distance < 0 ? expon - 1 : expon);
|
||||
if(val <= tools::min_value<T>())
|
||||
{
|
||||
limit = sign(T(distance)) * tools::min_value<T>();
|
||||
}
|
||||
BOOST_MATH_ASSERT(val > tools::min_value<T>()); // denorms already handled.
|
||||
T limit_distance = float_distance(val, limit);
|
||||
while(fabs(limit_distance) < abs(distance))
|
||||
{
|
||||
@@ -867,7 +850,7 @@ T float_advance_imp(T val, int distance, const std::false_type&, const Policy& p
|
||||
limit_distance = float_distance(val, limit);
|
||||
if(distance && (limit_distance == 0))
|
||||
{
|
||||
return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol);
|
||||
return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); // LCOV_EXCL_LINE should never get here!
|
||||
}
|
||||
}
|
||||
/*expon = 1 + ilogb(val);
|
||||
@@ -877,7 +860,7 @@ T float_advance_imp(T val, int distance, const std::false_type&, const Policy& p
|
||||
if(val != 0)
|
||||
diff = distance * scalbn(T(1), expon - std::numeric_limits<T>::digits);
|
||||
if(diff == 0)
|
||||
diff = distance * detail::get_smallest_value<T>();
|
||||
diff = distance * detail::get_smallest_value<T>(); // LCOV_EXCL_LINE This *should* be unreachable given that denorms are handled above.
|
||||
return val += diff;
|
||||
} // float_advance_imp
|
||||
|
||||
|
||||
@@ -569,7 +569,7 @@ test-suite special_fun :
|
||||
|
||||
[ run test_ldouble_simple.cpp /boost/test//boost_unit_test_framework ]
|
||||
# Needs to run in release mode, as it's rather slow:
|
||||
[ run test_next.cpp pch /boost/test//boost_unit_test_framework : : : release ]
|
||||
[ run test_next.cpp pch /boost/test//boost_unit_test_framework : : : [ check-target-builds ../config//is_ci_sanitizer_run "Sanitizer CI run" : debug : release ] ]
|
||||
[ run test_next_decimal.cpp pch /boost/test//boost_unit_test_framework : : : release ]
|
||||
[ run test_owens_t.cpp /boost/test//boost_unit_test_framework ]
|
||||
[ run test_polygamma.cpp test_instances//test_instances pch_light /boost/test//boost_unit_test_framework ]
|
||||
|
||||
@@ -61,6 +61,18 @@ void test_value(const T& val, const char* name)
|
||||
BOOST_CHECK_EQUAL(float_distance(float_advance(float_next(float_next(val)), 4), float_next(float_next(val))), -4);
|
||||
BOOST_CHECK_EQUAL(float_distance(float_advance(float_next(float_next(val)), -4), float_next(float_next(val))), 4);
|
||||
}
|
||||
#ifndef BOOST_MATH_NO_EXCEPTIONS
|
||||
BOOST_MATH_IF_CONSTEXPR(std::numeric_limits<T>::has_quiet_NaN)
|
||||
{
|
||||
BOOST_CHECK_THROW(float_distance(val, std::numeric_limits<T>::quiet_NaN()), std::domain_error);
|
||||
BOOST_CHECK_THROW(float_distance(std::numeric_limits<T>::quiet_NaN(), val), std::domain_error);
|
||||
}
|
||||
BOOST_MATH_IF_CONSTEXPR(std::numeric_limits<T>::has_infinity)
|
||||
{
|
||||
BOOST_CHECK_THROW(float_distance(val, std::numeric_limits<T>::infinity()), std::domain_error);
|
||||
BOOST_CHECK_THROW(float_distance(-std::numeric_limits<T>::infinity(), val), std::domain_error);
|
||||
}
|
||||
#endif
|
||||
if(val > 0)
|
||||
{
|
||||
T n = val + ulp(val);
|
||||
|
||||
@@ -54,6 +54,22 @@ void test_value(const T& val, const char* name)
|
||||
BOOST_CHECK_EQUAL(float_distance(float_prior(float_prior(val)), float_next(float_next(val))), 4);
|
||||
BOOST_CHECK_EQUAL(float_distance(float_prior(float_next(val)), val), 0);
|
||||
BOOST_CHECK_EQUAL(float_distance(float_next(float_prior(val)), val), 0);
|
||||
BOOST_CHECK_EQUAL(float_advance(val, 1), float_next(val));
|
||||
BOOST_CHECK_EQUAL(float_advance(val, -1), float_prior(val));
|
||||
|
||||
#ifndef BOOST_MATH_NO_EXCEPTIONS
|
||||
BOOST_MATH_IF_CONSTEXPR(std::numeric_limits<T>::has_quiet_NaN)
|
||||
{
|
||||
BOOST_CHECK_THROW(float_distance(val, std::numeric_limits<T>::quiet_NaN()), std::domain_error);
|
||||
BOOST_CHECK_THROW(float_distance(std::numeric_limits<T>::quiet_NaN(), val), std::domain_error);
|
||||
}
|
||||
BOOST_MATH_IF_CONSTEXPR(std::numeric_limits<T>::has_infinity)
|
||||
{
|
||||
BOOST_CHECK_THROW(float_distance(val, std::numeric_limits<T>::infinity()), std::domain_error);
|
||||
BOOST_CHECK_THROW(float_distance(-std::numeric_limits<T>::infinity(), val), std::domain_error);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_normalized_value(val))
|
||||
{
|
||||
BOOST_CHECK_EQUAL(float_prior(float_next(val)), val);
|
||||
@@ -197,6 +213,9 @@ void test_values(const T& val, const char* name)
|
||||
{
|
||||
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);
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_advance(std::numeric_limits<T>::quiet_NaN(), 3), std::domain_error);
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_advance(std::numeric_limits<T>::infinity(), 3), std::domain_error);
|
||||
BOOST_MATH_CHECK_THROW(boost::math::float_advance(-std::numeric_limits<T>::infinity(), 3), std::domain_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user