diff --git a/Number_types/include/CGAL/GMP/Gmpfr_type.h b/Number_types/include/CGAL/GMP/Gmpfr_type.h index 1e4d362abbb..d16c76a8663 100644 --- a/Number_types/include/CGAL/GMP/Gmpfr_type.h +++ b/Number_types/include/CGAL/GMP/Gmpfr_type.h @@ -37,6 +37,7 @@ #include #include #include +#include namespace CGAL{ @@ -861,28 +862,24 @@ std::pair,long> Gmpfr::to_interval_exp()const{ inline std::pair Gmpfr::to_integer_exp()const{ - if(is_zero()) - return std::make_pair(Gmpz(0),0); - Gmpz z; - long e=mpfr_get_z_exp(z.mpz(),fr()); - CGAL_assertion_msg(mpfr_get_emin()<=e && mpfr_get_emax()>=e, - "exponent out of range"); - if(mpz_sgn(z.mpz())!=0&&mpz_tstbit(z.mpz(),0)==0){ - unsigned long firstone=mpz_scan1(z.mpz(),0); - CGAL_assertion(mpz_divisible_2exp_p(z.mpz(),firstone)!=0); - Gmpz d(1); - mpz_mul_2exp(d.mpz(),d.mpz(),firstone); - CGAL_assertion(mpz_divisible_p(z.mpz(),d.mpz())!=0); - mpz_divexact(z.mpz(),z.mpz(),d.mpz()); - e+=firstone; - CGAL_assertion(mpfr_get_emax()>=e); - } - CGAL_assertion_code(Gmpfr::Precision_type p=mpz_sizeinbase(z.mpz(),2);) - CGAL_assertion_code(if(MPFR_PREC_MIN>p) p=MPFR_PREC_MIN;) - CGAL_assertion_code(Gmpfr test(z,p);) - CGAL_assertion_code(mpfr_mul_2si(test.fr(),test.fr(),e,GMP_RNDN);) - CGAL_assertion_msg(mpfr_equal_p(test.fr(),fr())!=0,"conversion error"); - return std::make_pair(z,e); + + if(this->is_zero()) + return std::make_pair(Gmpz(0),long(0)); + + Gmpz z; + long e=mpfr_get_z_exp(z.mpz(),this->fr()); + + long zeros = mpz_scan1(z.mpz(),0); + z >>= zeros; + e += zeros; + + CGAL_postcondition(z % 2 != 0); + CGAL_postcondition_code(if (e >= 0)) + CGAL_postcondition( (*this) == (Gmpfr(z)) * CGAL::ipower(Gmpfr(2), e)); + CGAL_postcondition_code(else) + CGAL_postcondition( (*this) == (Gmpfr(z)) / CGAL::ipower(Gmpfr(2),-e)); + + return std::make_pair(z,e); } inline