mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-07-21 13:23:49 +00:00
Intended to address issue722
This commit is contained in:
@@ -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
@@ -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>();
|
||||
|
||||
@@ -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>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user