Specialize conversion of mpz_int to interval

copy-paste of the code for Gmpz/mpz_class
This commit is contained in:
Marc Glisse 2019-01-22 14:32:08 +01:00
parent a5d89b1f33
commit 92f55fb8ca
1 changed files with 37 additions and 2 deletions

View File

@ -224,9 +224,44 @@ struct RET_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_rat
: RET_boost_mp_base <NT> {};
#ifdef CGAL_USE_MPFR
// Because of this full specialization, things get instantiated more eagerly. Make it artificially partial if necessary.
// Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary.
template <>
struct RET_boost_mp <boost::multiprecision::mpq_rational, boost::mpl::int_<boost::multiprecision::number_kind_rational> >
struct RET_boost_mp <boost::multiprecision::mpz_int>
: RET_boost_mp_base <boost::multiprecision::mpz_int> {
typedef boost::multiprecision::mpz_int Type;
struct To_interval
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
std::pair<double, double>
operator()(const Type& x) const {
#if MPFR_VERSION_MAJOR >= 3
MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */
int r = mpfr_set_z (y, x.backend().data(), MPFR_RNDA);
double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */
if (r == 0 && is_finite (i))
return std::pair<double, double>(i, i);
else
{
double s = nextafter (i, 0);
if (i < 0)
return std::pair<double, double>(i, s);
else
return std::pair<double, double>(s, i);
}
#else
mpfr_t y;
mpfr_init2 (y, 53); /* Assume IEEE-754 */
mpfr_set_z (y, x.backend().data(), GMP_RNDD);
double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */
mpfr_set_z (y, x.backend().data(), GMP_RNDU);
double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */
mpfr_clear (y);
return std::pair<double, double>(i, s);
#endif
}
};
};
template <>
struct RET_boost_mp <boost::multiprecision::mpq_rational>
: RET_boost_mp_base <boost::multiprecision::mpq_rational> {
typedef boost::multiprecision::mpq_rational Type;
struct To_interval