to_integer_exp returns unique pair

This commit is contained in:
Michael Hemmer 2010-02-15 20:57:04 +00:00
parent 72af5b7463
commit c1ca042676
1 changed files with 19 additions and 22 deletions

View File

@ -37,6 +37,7 @@
#include <string>
#include <limits>
#include <CGAL/Uncertain.h>
#include <CGAL/ipower.h>
namespace CGAL{
@ -861,28 +862,24 @@ std::pair<std::pair<double,double>,long> Gmpfr::to_interval_exp()const{
inline
std::pair<Gmpz,long> 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