Skip to content

Commit

Permalink
Merge pull request #606 from boostorg/mpfr_error_handling
Browse files Browse the repository at this point in the history
Correct error handling in mpfr specfun overloads.
  • Loading branch information
jzmaddock authored Mar 2, 2024
2 parents 42a3edf + fe60def commit 438b9fc
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
8 changes: 7 additions & 1 deletion include/boost/multiprecision/detail/default_ops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2486,7 +2486,7 @@ void raise_rounding_error(T1, T2, T3, T4, T5)
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void raise_overflow_error(T1, T2, T3, T4, T5)
{
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Overflow error"));
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Overflow error"));
}

template <typename T1, typename T2, typename T3, typename T4, typename T5>
Expand All @@ -2495,6 +2495,12 @@ void raise_evaluation_error(T1, T2, T3, T4, T5)
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Evaluation error"));
}

template <typename T1, typename T2, typename T3, typename T4, typename T5>
void raise_domain_error(T1, T2, T3, T4, T5)
{
BOOST_MP_THROW_EXCEPTION(std::domain_error("Domain error"));
}

template <typename T, typename... Args>
struct is_policy
{
Expand Down
10 changes: 9 additions & 1 deletion include/boost/multiprecision/mpfr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2802,6 +2802,8 @@ inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<D
boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);

boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
if (mpfr_nan_p(arg.backend().data()))
return policies::raise_domain_error("cbrt<%1%>(%1%)", "Input is a NaN", result, Policy());
mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
if (mpfr_inf_p(result.backend().data()))
return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("cbrt<%1%>(%1%)", nullptr, Policy());
Expand All @@ -2821,6 +2823,8 @@ inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<D
boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);

boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
if (mpfr_nan_p(arg.backend().data()))
return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
if (mpfr_inf_p(result.backend().data()))
return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erf<%1%>(%1%)", nullptr, pol);
Expand All @@ -2840,6 +2844,8 @@ inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<D
boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);

boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
if (mpfr_nan_p(arg.backend().data()))
return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
if (mpfr_inf_p(result.backend().data()))
return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erfc<%1%>(%1%)", nullptr, pol);
Expand All @@ -2859,6 +2865,8 @@ inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<D
boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);

boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
if (mpfr_nan_p(arg.backend().data()))
return policies::raise_domain_error("erf<%1%>(%1%)", "Input is a NaN", result, pol);
mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
if (mpfr_inf_p(result.backend().data()))
return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("expm1<%1%>(%1%)", nullptr, pol);
Expand All @@ -2867,7 +2875,7 @@ inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<D
return result;
}
template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
{
return expm1(arg, policies::policy<>());
}
Expand Down

0 comments on commit 438b9fc

Please sign in to comment.