mirror of https://github.com/CGAL/cgal
to_integer_exp returns unique pair
This commit is contained in:
parent
72af5b7463
commit
c1ca042676
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue