Intended to address issue722

This commit is contained in:
ckormanyos
2025-07-12 16:01:21 +02:00
parent 1f0385a0f5
commit b5725b5ba8
3 changed files with 46 additions and 27 deletions
@@ -511,11 +511,12 @@ inline void eval_pow(T& result, const T& x, const T& a)
}
int type = eval_fpclassify(x);
int fpc_a = eval_fpclassify(a);
switch (type)
{
case FP_ZERO:
switch (eval_fpclassify(a))
switch (fpc_a)
{
case FP_ZERO:
result = si_type(1);
@@ -643,7 +644,7 @@ inline void eval_pow(T& result, const T& x, const T& a)
eval_floor(result, a);
// -1^INF is a special case in C99:
if ((x.compare(si_type(-1)) == 0) && (eval_fpclassify(a) == FP_INFINITE))
if ((x.compare(si_type(-1)) == 0) && (fpc_a == FP_INFINITE))
{
result = si_type(1);
}
@@ -661,7 +662,21 @@ inline void eval_pow(T& result, const T& x, const T& a)
}
else if (type == FP_INFINITE)
{
result = std::numeric_limits<number<T, et_on> >::infinity().backend();
BOOST_IF_CONSTEXPR (std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
{
if (fpc_a == FP_NAN)
{
result = std::numeric_limits<number<T, et_on> >::quiet_NaN().backend();
}
else
{
result = std::numeric_limits<number<T, et_on> >::infinity().backend();
}
}
else
{
result = std::numeric_limits<number<T, et_on> >::infinity().backend();
}
}
else BOOST_IF_CONSTEXPR (std::numeric_limits<number<T, et_on> >::has_quiet_NaN)
{
+27 -24
View File
@@ -129,37 +129,37 @@ namespace local {
#if (defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_BIN_FLOAT) || defined(TEST_CPP_DOUBLE_FLOAT) || defined(TEST_MPF_50))
// These were the only ones I checked locally at the moment that use random tests.
// These were the only ones I checked locally at the moment.
// TEST_MPF_50 is included because it does its has_quiet_NaN is false.
// And this helps verify the constexpr logic of test_issue722().
template <class T>
void test_issue722()
{
// TBD: When issue722 gets resolved, test some of the other types.
#if defined(TEST_CPP_DEC_FLOAT)
std::mt19937_64 gen { };
gen.seed(static_cast<typename std::mt19937_64::result_type>(std::clock()));
std::uniform_real_distribution<float>
dist
(
static_cast<float>(1.01L),
static_cast<float>(1.04L)
);
for (int index = 0; index < 8; ++index)
BOOST_IF_CONSTEXPR (std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::has_infinity && std::numeric_limits<T>::has_quiet_NaN)
{
static_cast<void>(index);
std::mt19937_64 gen { };
const T inf_or_zero_arg = T(-std::numeric_limits<T>::infinity() * dist(gen));
gen.seed(static_cast<typename std::mt19937_64::result_type>(std::clock()));
const T pow_inf_or_zero_to_the_nan = pow(inf_or_zero_arg, std::numeric_limits<T>::quiet_NaN() * dist(gen));
std::uniform_real_distribution<float>
dist
(
static_cast<float>(1.01L),
static_cast<float>(1.04L)
);
BOOST_CHECK((boost::multiprecision::isnan)(pow_inf_or_zero_to_the_nan));
for (int index = 0; index < 8; ++index)
{
static_cast<void>(index);
const T neg_inf = T(-std::numeric_limits<T>::infinity() * dist(gen));
const T pow_neg_inf_to_the_nan = pow(neg_inf, std::numeric_limits<T>::quiet_NaN() * dist(gen));
BOOST_CHECK((boost::multiprecision::isnan)(pow_neg_inf_to_the_nan));
}
}
#endif
}
#endif // (defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_BIN_FLOAT) || defined(TEST_CPP_DOUBLE_FLOAT) || defined(TEST_MPF_50))
@@ -208,7 +208,7 @@ void test()
BOOST_CHECK_EQUAL(pow(T(1), 2), 1);
#if (defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_BIN_FLOAT) || defined(TEST_CPP_DOUBLE_FLOAT) || defined(TEST_MPF_50))
// These were the only ones I checked locally at the moment that use random tests.
// These were the only ones I checked locally at the moment.
std::mt19937_64 gen { };
@@ -230,7 +230,7 @@ void test()
#if (defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_BIN_FLOAT) || defined(TEST_CPP_DOUBLE_FLOAT) || defined(TEST_MPF_50))
// These were the only ones I checked locally at the moment that use random tests.
// These were the only ones I checked locally at the moment.
for (int npow = -8; npow < 8; ++npow)
{
@@ -339,6 +339,7 @@ int main()
#ifdef TEST_MPF_50
test<boost::multiprecision::mpf_float_50>();
test<boost::multiprecision::mpf_float_100>();
test_issue722<boost::multiprecision::mpf_float_50>();
#endif
#ifdef TEST_MPFR_50
test<boost::multiprecision::mpfr_float_50>();
@@ -351,6 +352,7 @@ int main()
#ifdef TEST_CPP_DEC_FLOAT
test<boost::multiprecision::cpp_dec_float_50>();
test<boost::multiprecision::cpp_dec_float_100>();
test_issue722<boost::multiprecision::cpp_dec_float_50>();
#ifndef SLOW_COMPLER
// Some "peculiar" digit counts which stress our code:
test<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<65> > >();
@@ -372,6 +374,7 @@ int main()
#ifdef TEST_CPP_BIN_FLOAT
test<boost::multiprecision::cpp_bin_float_50>();
test<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<35, boost::multiprecision::digit_base_10, std::allocator<char>, long long> > >();
test_issue722<boost::multiprecision::cpp_bin_float_50>();
#endif
#ifdef TEST_CPP_DOUBLE_FLOAT
test<boost::multiprecision::cpp_double_double>();
+1
View File
@@ -2306,6 +2306,7 @@ int main()
test_c99_appendix_F<boost::multiprecision::number<boost::multiprecision::logged_adaptor<boost::multiprecision::mpfr_float_backend<50> > > >();
#endif
#ifdef TEST_CPP_DOUBLE_FLOAT
test<boost::multiprecision::cpp_double_float>();
test<boost::multiprecision::cpp_double_double>();
test<boost::multiprecision::cpp_double_long_double>();