From 239fd62dbec8bca1db3b4e46e2df8dc13c47bfce Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 21 Nov 2013 13:04:20 +0000 Subject: [PATCH] Add some better error checks to interval construction. [SVN r86779] --- include/boost/multiprecision/mpfi.hpp | 37 +++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/include/boost/multiprecision/mpfi.hpp b/include/boost/multiprecision/mpfi.hpp index e0c628fe7..76605be02 100644 --- a/include/boost/multiprecision/mpfi.hpp +++ b/include/boost/multiprecision/mpfi.hpp @@ -179,6 +179,8 @@ struct mpfi_float_imp } mpfi_float_imp& operator = (const char* s) { + using default_ops::eval_fpclassify; + if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -203,7 +205,22 @@ struct mpfi_float_imp part.erase(); b = part.c_str(); - mpfi_interv_fr(m_data, a.data(), b.data()); + if(eval_fpclassify(a) == FP_NAN) + { + mpfi_set_fr(this->data(), a.data()); + } + else if(eval_fpclassify(b) == FP_NAN) + { + mpfi_set_fr(this->data(), b.data()); + } + else + { + if(a.compare(b) > 0) + { + BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end).")); + } + mpfi_interv_fr(m_data, a.data(), b.data()); + } } else if(mpfi_set_str(m_data, s, 10) != 0) { @@ -745,7 +762,23 @@ inline void eval_convert_to(long double* result, const mpfi_float_backend inline void assign_components(mpfi_float_backend& result, const mpfr_float_backend& a, const mpfr_float_backend& b) { - mpfi_interv_fr(result.data(), a.data(), b.data()); + using default_ops::eval_fpclassify; + if(eval_fpclassify(a) == FP_NAN) + { + mpfi_set_fr(result.data(), a.data()); + } + else if(eval_fpclassify(b) == FP_NAN) + { + mpfi_set_fr(result.data(), b.data()); + } + else + { + if(a.compare(b) > 0) + { + BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end).")); + } + mpfi_interv_fr(result.data(), a.data(), b.data()); + } } template