[multiprecision] Empty intervals and intervals with NaN check
Hello. In MPFI documentation it is said that "MPFI functions operate on valid intervals ..., their behavior with non-valid intervals as input is undefined". Are intervals checked in Boost Multiprecision library whether they are invalid? Can this be easily done using Boost? Kind regards, Petr.
In MPFI documentation it is said that "MPFI functions operate on valid intervals ..., their behavior with non-valid intervals as input is undefined". Are intervals checked in Boost Multiprecision library whether they are invalid? Can this be easily done using Boost? Kind regards, Petr.
No, the class is a very thin wrapper around mpfi so there's practically no error checking. I really should add some error checks to the functions that create new intervals (i.e. assignment operators from two "components"): I'll do that shortly. You can check intervals yourself by accessing the individual components, for example with: assert(lower(my_interval) <= upper(my_interval)); You can also get the underlying mpfi_t via: my_interval.backend().data(); Checking for infinities/NaN's etc can be done with the usual isinf, isnan, isfinite, fpclassify etc. These rely on mpfi's functions internally, I'm not sure what happens to these if you've managed to create an invalid interval somehow - will check. HTH, John.
No, the class is a very thin wrapper around mpfi so there's practically no error checking. I really should add some error checks to the functions that create new intervals (i.e. assignment operators from two "components"): I'll do that shortly.
Here's the patch for better error checks going in Trunk, hopefully that
should stop most invalid intervals from ever occurring in the first place:
Index: mpfi.hpp
===================================================================
--- mpfi.hpp (revision 86537)
+++ mpfi.hpp (working copy)
@@ -179,6 +179,8 @@
}
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 @@
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 @@
template
21.11.2013 17:04, John Maddock пишет:
No, the class is a very thin wrapper around mpfi so there's practically no error checking. I really should add some error checks to the functions that create new intervals (i.e. assignment operators from two "components"): I'll do that shortly.
Here's the patch for better error checks going in Trunk, hopefully that should stop most invalid intervals from ever occurring in the first place:
Index: mpfi.hpp =================================================================== --- mpfi.hpp (revision 86537) +++ mpfi.hpp (working copy) @@ -179,6 +179,8 @@ } 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 @@ 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 @@ template
inline void assign_components(mpfi_float_backend<D1>& 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
John. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Probably it will be better to allow a user to select: check empty intervals and NaN (during creation and assignment too) or not. Kind regards, Petr.
participants (2)
-
John Maddock
-
Александров Петр