mirror of https://github.com/CGAL/cgal
Some changes in the Gmpfi and Gmpfr classes:
-eliminated useless 'inline' keywords; -wrapped to 80 columns; -added extra assertions in functions; -eliminated the reference counting from Gmpfi, since the reference counted endpoints do the job; -minor details in documentation.
This commit is contained in:
parent
bdad265446
commit
1c2f4582c0
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
\ccDefinition
|
||||
|
||||
An object of the class \ccc{Gmpfi} is a closed interval, whith
|
||||
endpoints represented as \mpfr\ floating-point numbers. An interval can
|
||||
have finite or infinite endpoints and its meaning is straightforward.
|
||||
It can also have one (or both) NaN endpoint(s): this indicates that an
|
||||
invalid operation has been performed and that the resulting interval
|
||||
has no mathematical meaning.
|
||||
An object of the class \ccc{Gmpfi} is a closed interval, whith endpoints
|
||||
represented as \ccc{Gmpfr} floating-point numbers. An interval can have
|
||||
finite or infinite endpoints and its meaning is straightforward. It can
|
||||
also have one (or both) \ccc{NaN} endpoint(s): this indicates that an
|
||||
invalid operation has been performed and that the resulting interval has no
|
||||
mathematical meaning.
|
||||
|
||||
All the operations of \ccc{Gmpfi} were designed in such a way that the
|
||||
mathematical correct result is always contained in the resulting interval.
|
||||
|
|
@ -31,13 +31,12 @@ and \verb-long double-.
|
|||
|
||||
\ccCreation
|
||||
|
||||
All the constructors accept an optional last argument: a precision
|
||||
(a \ccc{Precision_type}, which can be used to specify the precision of
|
||||
the \ccc{Gmpfr} endpoints. If none is specified, the default precision
|
||||
will be used. As the endpoints are represented with a fixed number of
|
||||
bits, they may need to be rounded. In this case, the number from which
|
||||
the \ccc{Gmpfi} was constructed is guaranteed to be included in the
|
||||
constructed interval.
|
||||
All the constructors accept an optional last argument: a precision (a
|
||||
\ccc{Precision_type}, which can be used to specify the precision of the
|
||||
\ccc{Gmpfr} endpoints. If none is specified, the default precision will be
|
||||
used. As the endpoints are represented with a fixed number of bits, they
|
||||
may need to be rounded. In this case, the number from which the \ccc{Gmpfi}
|
||||
was constructed is guaranteed to be included in the constructed interval.
|
||||
|
||||
\ccCreationVariable{i}
|
||||
|
||||
|
|
@ -73,7 +72,7 @@ constructed interval.
|
|||
Gmpfi(std::pair<const L&,const R&> endpoints,
|
||||
Precision_type p=get_default_precision());}
|
||||
{creates a \ccc{Gmpfi} initialized with endpoints
|
||||
\ccc{endpoints.first} and \ccc{endpoints.second}. \ccc{L} and
|
||||
\ccc{endpoints.first} and \ccc{endpoints.second}. \ccc{L} and
|
||||
\ccc{R} are types from which \ccc{Gmpfr} can be constructed
|
||||
from. The rounding of the endpoints will guarantee that
|
||||
\([\ccc{endpoints.first},\ccc{endpoints.second}]\) is included in
|
||||
|
|
@ -113,8 +112,8 @@ constructed interval.
|
|||
|
||||
Arithmetic operators \verb=+=, \verb=-=, \verb=*=\ and \verb=/=\ are
|
||||
overloaded, but special care must be taken when applying them. The
|
||||
precision of an operation between two \ccc{Gmpfi}s is defined as
|
||||
the maximum of the operands precision and the default precision.
|
||||
precision of an operation between two \ccc{Gmpfi}s is defined as the
|
||||
maximum of the operands precision and the default precision.
|
||||
|
||||
The second operand of the former operations can be a \verb=Gmpfi=,
|
||||
\verb=Gmpfr=, \verb=int=, \verb=long=, \verb=unsigned=,
|
||||
|
|
@ -191,21 +190,21 @@ Other arithmetic functions provided by the class are:
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\ccHeading{Comparisons}
|
||||
|
||||
The semantics of the comparison operators is the same than
|
||||
on \ccc{Interval_nt<Protected>}. The result of the comparison
|
||||
is always an \ccc{Uncertain<bool>} (this type is convertible to
|
||||
\ccc{bool}, but may throw an exception). If compared intervals have
|
||||
no common points, the result is \ccc{true} or \ccc{false}; otherwise,
|
||||
The semantics of the comparison operators is the same than on
|
||||
\ccc{Interval_nt<Protected>}. The result of the comparison is always an
|
||||
\ccc{Uncertain<bool>} (this type is convertible to \ccc{bool}, but may
|
||||
throw an exception). If compared intervals have no common points, the
|
||||
result is \ccc{true} or \ccc{false}; otherwise,
|
||||
\ccc{Uncertain<bool>::indeterminate()} will be returned.
|
||||
|
||||
In the same way, we can explain the semantics of
|
||||
\ccc{Uncertain<Comparison\_result>} and \ccc{Uncertain<Sign>}.
|
||||
|
||||
With the semantics described above, this class provides comparisons between
|
||||
\ccc{Gmpfi} and \ccc{Gmpfi}, \ccc{Gmpfr}, \ccc{long},
|
||||
\ccc{unsigned long}, \ccc{int}, \ccc{double}, \ccc{Gmpz}
|
||||
and \ccc{Gmpq}. Comparison operators \verb-==-, \verb-!=-, \verb->-,
|
||||
\verb-<-, \verb->=- \ and \verb-<=- \ are overloaded.
|
||||
\ccc{Gmpfi} and \ccc{Gmpfi}, \ccc{Gmpfr}, \ccc{long}, \ccc{unsigned long},
|
||||
\ccc{int}, \ccc{double}, \ccc{Gmpz} and \ccc{Gmpq}. Comparison operators
|
||||
\verb-==-, \verb-!=-, \verb->-, \verb-<-, \verb->=- \ and \verb-<=- \ are
|
||||
overloaded.
|
||||
|
||||
The class provides also functions to test efficiently some special kinds
|
||||
of comparisons:
|
||||
|
|
@ -233,7 +232,8 @@ of comparisons:
|
|||
{Returns \ccc{true} iff both endpoints are equal.}
|
||||
|
||||
\ccMethod{bool is_nan()const;}
|
||||
{Returns \ccc{true} iff at least one of the endpoints is NaN.}
|
||||
{Returns \ccc{true} iff at least one of the endpoints is
|
||||
\ccc{NaN}.}
|
||||
|
||||
\ccMethod{bool is_inf()const;}
|
||||
{Returns \ccc{true} iff at least one of the endpoints is plus or
|
||||
|
|
@ -300,7 +300,8 @@ of comparisons:
|
|||
|
||||
|
||||
\ccImplementation
|
||||
\ccc{Gmpfi}s are reference counted.
|
||||
All interval operations are performed by the \mpfi~library. The class
|
||||
\ccc{Gmpfi} is not reference counted, but its members are.
|
||||
|
||||
\ccSeeAlso
|
||||
\ccRefIdfierPage{Gmpfr}\\
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@
|
|||
#include <CGAL/GMP/Gmpfr_type.h>
|
||||
#include <mpfi.h>
|
||||
#include <boost/operators.hpp>
|
||||
#include <CGAL/Handle_for.h>
|
||||
#include <CGAL/Uncertain.h>
|
||||
#ifdef CGAL_HAS_THREADS
|
||||
# include <boost/thread/tss.hpp>
|
||||
#endif
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace CGAL{
|
||||
|
||||
|
|
@ -71,16 +71,6 @@ Uncertain<bool> operator<(const Gmpfi&,const Gmpq&);
|
|||
Uncertain<bool> operator>(const Gmpfi&,const Gmpq&);
|
||||
Uncertain<bool> operator==(const Gmpfi&,const Gmpq&);
|
||||
|
||||
struct Gmpfi_rep{
|
||||
mpfi_t floating_point_interval;
|
||||
bool clear_on_destruction;
|
||||
Gmpfi_rep():clear_on_destruction(true){}
|
||||
~Gmpfi_rep(){
|
||||
if(clear_on_destruction)
|
||||
mpfi_clear(floating_point_interval);
|
||||
}
|
||||
};
|
||||
|
||||
// the default precision of Gmpfi is the size of a double's mantissa
|
||||
#ifdef IEEE_DBL_MANT_DIG
|
||||
# define CGAL_GMPFI_DEFAULT_PRECISION IEEE_DBL_MANT_DIG
|
||||
|
|
@ -97,7 +87,6 @@ struct Gmpfi_rep{
|
|||
#endif
|
||||
|
||||
class Gmpfi:
|
||||
Handle_for<Gmpfi_rep>,
|
||||
boost::ordered_euclidian_ring_operators1<Gmpfi,
|
||||
boost::ordered_euclidian_ring_operators2<Gmpfi,Gmpfr,
|
||||
boost::ordered_euclidian_ring_operators2<Gmpfi,long,
|
||||
|
|
@ -109,7 +98,47 @@ class Gmpfi:
|
|||
boost::ordered_euclidian_ring_operators2<Gmpfi,Gmpq
|
||||
> > > > > > > > >
|
||||
{
|
||||
typedef Handle_for<Gmpfi_rep> Base;
|
||||
private:
|
||||
|
||||
// The endpoints of the interval are represented by two objects of
|
||||
// type Gmpfr. To apply MPFI functions to this interval, the
|
||||
// pointers to the data in _left and _right are copied to the
|
||||
// _interval structure using the function mpfi(). After the
|
||||
// operation, the function gather_bounds should be called to put
|
||||
// back the result of the operation in _left and _right.
|
||||
Gmpfr _left,_right;
|
||||
mutable __mpfi_struct _interval;
|
||||
|
||||
bool is_unique(){
|
||||
#ifdef CGAL_GMPFR_NO_REFCOUNT
|
||||
return true;
|
||||
#else
|
||||
return(_left.is_unique()&&_right.is_unique());
|
||||
#endif
|
||||
}
|
||||
|
||||
// swaps the contents of this object and another one
|
||||
void swap(Gmpfi &fi){
|
||||
std::swap(*this,fi);
|
||||
}
|
||||
|
||||
// after calling a library function that modifies the data in the
|
||||
// structure _interval, this function has to be called in order to
|
||||
// copy the data in _interval to _left and _right
|
||||
void gather_bounds(){
|
||||
mpfr_custom_init_set(
|
||||
_left.fr(),
|
||||
mpfr_custom_get_kind(&_interval.left),
|
||||
mpfr_custom_get_exp(&_interval.left),
|
||||
mpfr_get_prec(&_interval.left),
|
||||
mpfr_custom_get_mantissa(&_interval.left));
|
||||
mpfr_custom_init_set(
|
||||
_right.fr(),
|
||||
mpfr_custom_get_kind(&_interval.right),
|
||||
mpfr_custom_get_exp(&_interval.right),
|
||||
mpfr_get_prec(&_interval.right),
|
||||
mpfr_custom_get_mantissa(&_interval.right));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -117,51 +146,50 @@ class Gmpfi:
|
|||
|
||||
// access
|
||||
|
||||
inline mpfi_srcptr mpfi()const{
|
||||
return Ptr()->floating_point_interval;
|
||||
mpfi_srcptr mpfi()const{
|
||||
_interval.left=*_left.fr();
|
||||
_interval.right=*_right.fr();
|
||||
CGAL_assertion(mpfr_equal_p(_left.fr(),&_interval.left)!=0 &&
|
||||
mpfr_equal_p(_right.fr(),&_interval.right)!=0);
|
||||
return &_interval;
|
||||
}
|
||||
|
||||
inline mpfr_srcptr left_mpfr()const{
|
||||
return &(mpfi()->left);
|
||||
mpfi_ptr mpfi(){
|
||||
_interval.left=*_left.fr();
|
||||
_interval.right=*_right.fr();
|
||||
CGAL_assertion(mpfr_equal_p(_left.fr(),&_interval.left)!=0 &&
|
||||
mpfr_equal_p(_right.fr(),&_interval.right)!=0);
|
||||
return &_interval;
|
||||
}
|
||||
|
||||
inline mpfr_srcptr right_mpfr()const{
|
||||
return &(mpfi()->right);
|
||||
mpfr_srcptr left_mpfr()const{
|
||||
return _left.fr();
|
||||
}
|
||||
|
||||
inline mpfi_ptr mpfi(){
|
||||
return ptr()->floating_point_interval;
|
||||
mpfr_srcptr right_mpfr()const{
|
||||
return _right.fr();
|
||||
}
|
||||
|
||||
inline Gmpfr inf()const{
|
||||
return Gmpfr(left_mpfr());
|
||||
Gmpfr inf()const{
|
||||
return _left;
|
||||
}
|
||||
|
||||
inline Gmpfr sup()const{
|
||||
return Gmpfr(right_mpfr());
|
||||
}
|
||||
|
||||
inline
|
||||
void dont_clear_on_destruction(){
|
||||
ptr()->clear_on_destruction=false;
|
||||
Gmpfr sup()const{
|
||||
return _right;
|
||||
}
|
||||
|
||||
// construction
|
||||
|
||||
Gmpfi(){
|
||||
mpfi_init(mpfi());
|
||||
}
|
||||
Gmpfi(){}
|
||||
~Gmpfi(){}
|
||||
|
||||
#define CGAL_GMPFI_CONSTRUCTOR_FROM_SCALAR(_type) \
|
||||
Gmpfi(const _type &t, \
|
||||
Gmpfi::Precision_type p=Gmpfi::get_default_precision()){ \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
Gmpfr l(t,std::round_toward_neg_infinity,p), \
|
||||
r(t,std::round_toward_infinity,p); \
|
||||
l.dont_clear_on_destruction(); \
|
||||
r.dont_clear_on_destruction(); \
|
||||
mpfi()->left=*(l.fr()); \
|
||||
mpfi()->right=*(r.fr()); \
|
||||
_left=Gmpfr(t,std::round_toward_neg_infinity,p); \
|
||||
_right=Gmpfr(t,std::round_toward_infinity,p); \
|
||||
CGAL_assertion(_left<=t&&_right>=t); \
|
||||
}
|
||||
|
||||
CGAL_GMPFI_CONSTRUCTOR_FROM_SCALAR(long);
|
||||
|
|
@ -176,71 +204,94 @@ CGAL_GMPFI_CONSTRUCTOR_FROM_SCALAR(Gmpz);
|
|||
Gmpfi(const Gmpq &q,
|
||||
Gmpfi::Precision_type p=Gmpfi::get_default_precision()){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
Gmpfr l(0,p),r(0,p);
|
||||
mpfr_set_q(l.fr(),q.mpq(),GMP_RNDD);
|
||||
mpfr_set_q(r.fr(),q.mpq(),GMP_RNDU);
|
||||
l.dont_clear_on_destruction();
|
||||
r.dont_clear_on_destruction();
|
||||
mpfi()->left=*(l.fr());
|
||||
mpfi()->right=*(r.fr());
|
||||
_left=Gmpfr(0,p);
|
||||
_right=Gmpfr(0,p);
|
||||
mpfr_set_q(_left.fr(),q.mpq(),GMP_RNDD);
|
||||
mpfr_set_q(_right.fr(),q.mpq(),GMP_RNDU);
|
||||
CGAL_assertion(_left<=q&&_right>=q);
|
||||
}
|
||||
|
||||
Gmpfi(mpfi_srcptr i,Gmpfi::Precision_type p=0){
|
||||
if((p==0)||
|
||||
(p==mpfr_get_prec(&(i->left))
|
||||
&&p==mpfr_get_prec(&(i->right)))){
|
||||
mpfi()->left=i->left;
|
||||
mpfi()->right=i->right;
|
||||
dont_clear_on_destruction();
|
||||
}else{
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfi_init2(mpfi(),p);
|
||||
mpfi_set(mpfi(),i);
|
||||
}
|
||||
Gmpfi(mpfi_srcptr i){
|
||||
_left=Gmpfr(&(i->left));
|
||||
_right=Gmpfr(&(i->right));
|
||||
}
|
||||
|
||||
Gmpfi(mpfi_srcptr i,Gmpfi::Precision_type p){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
_left=Gmpfr(&(i->left),std::round_toward_neg_infinity,p);
|
||||
_right=Gmpfr(&(i->right),std::round_toward_infinity,p);
|
||||
CGAL_assertion(mpfr_cmp(_left.fr(),&(i->left))<=0 &&
|
||||
mpfr_cmp(_right.fr(),&(i->right))>=0);
|
||||
}
|
||||
|
||||
Gmpfi(const Gmpfr &f,
|
||||
Gmpfi::Precision_type p=Gmpfi::get_default_precision()){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfi_init2(mpfi(),p);
|
||||
mpfi_set_fr(mpfi(),f.fr());
|
||||
_left=Gmpfr(f,std::round_toward_neg_infinity,p);
|
||||
_right=Gmpfr(f,std::round_toward_infinity,p);
|
||||
CGAL_assertion(_left<=f&&_right>=f);
|
||||
}
|
||||
|
||||
Gmpfi(const Gmpfr &left,
|
||||
const Gmpfr &right,
|
||||
Gmpfi(const Gmpfr &l,
|
||||
const Gmpfr &r,
|
||||
Gmpfi::Precision_type p=Gmpfi::get_default_precision()){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfi_init2(mpfi(),p);
|
||||
mpfi_interv_fr(mpfi(),left.fr(),right.fr());
|
||||
_left=Gmpfr(l,std::round_toward_neg_infinity,p);
|
||||
_right=Gmpfr(r,std::round_toward_infinity,p);
|
||||
CGAL_assertion(_left<=l||(_left.is_nan()&&l.is_nan()));
|
||||
CGAL_assertion(_right>=l||(_right.is_nan()&&r.is_nan()));
|
||||
}
|
||||
|
||||
Gmpfi(std::pair<const Gmpfr,const Gmpfr> endpoints,
|
||||
Gmpfi(std::pair<const Gmpfr,const Gmpfr> bounds,
|
||||
Gmpfi::Precision_type p=Gmpfi::get_default_precision()){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfi_init2(mpfi(),p);
|
||||
mpfi_interv_fr(
|
||||
mpfi(),
|
||||
endpoints.first.fr(),
|
||||
endpoints.second.fr());
|
||||
_left=Gmpfr(bounds.first,std::round_toward_neg_infinity,p);
|
||||
_right=Gmpfr(bounds.second,std::round_toward_infinity,p);
|
||||
CGAL_assertion(_left<=bounds.first||
|
||||
(_left.is_nan()&&bounds.first.is_nan()));
|
||||
CGAL_assertion(_right>=bounds.second||
|
||||
(_right.is_nan()&&bounds.second.is_nan()));
|
||||
}
|
||||
|
||||
template<class L,class R>
|
||||
Gmpfi(std::pair<const L&,const R&> endpoints,
|
||||
Gmpfi(std::pair<const L&,const R&> bounds,
|
||||
Gmpfi::Precision_type p=get_default_precision()){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
Gmpfr l(endpoints.first,std::round_toward_neg_infinity,p),
|
||||
r(endpoints.second,std::round_toward_infinity,p);
|
||||
l.dont_clear_on_destruction();
|
||||
r.dont_clear_on_destruction();
|
||||
mpfi()->left=*(l.fr());
|
||||
mpfi()->right=*(r.fr());
|
||||
_left=Gmpfr(bounds.first,std::round_toward_neg_infinity,p);
|
||||
_right=Gmpfr(bounds.second,std::round_toward_infinity,p);
|
||||
CGAL_assertion(_left<=bounds.first&&_right>=bounds.second);
|
||||
}
|
||||
|
||||
// copy assignment operator
|
||||
Gmpfi& operator=(const Gmpfi &a){
|
||||
_left=a.inf();
|
||||
_right=a.sup();
|
||||
CGAL_assertion(_left==a.inf()||
|
||||
(_left.is_nan()&&a.inf().is_nan()));
|
||||
CGAL_assertion(_right==a.sup()||
|
||||
(_right.is_nan()&&a.sup().is_nan()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy constructor without precision
|
||||
Gmpfi(const Gmpfi &a){
|
||||
_left=a.inf();
|
||||
_right=a.sup();
|
||||
CGAL_assertion(_left==a.inf()||
|
||||
(_left.is_nan()&&a.inf().is_nan()));
|
||||
CGAL_assertion(_right==a.sup()||
|
||||
(_right.is_nan()&&a.sup().is_nan()));
|
||||
}
|
||||
|
||||
// copy constructor with precision
|
||||
Gmpfi(const Gmpfi &a,Gmpfi::Precision_type p){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfi_init2(mpfi(),p);
|
||||
mpfi_set(mpfi(),a.mpfi());
|
||||
_left=Gmpfr(a.inf(),std::round_toward_neg_infinity,p);
|
||||
_right=Gmpfr(a.sup(),std::round_toward_infinity,p);
|
||||
CGAL_assertion(_left<=a.inf()||
|
||||
(_left.is_nan()&&a.inf().is_nan()));
|
||||
CGAL_assertion(_right>=a.sup()||
|
||||
(_right.is_nan()&&a.sup().is_nan()));
|
||||
}
|
||||
|
||||
// default precision
|
||||
|
|
@ -385,7 +436,9 @@ Gmpfi::Precision_type Gmpfi::set_default_precision(Gmpfi::Precision_type prec){
|
|||
|
||||
inline
|
||||
Gmpfi::Precision_type Gmpfi::get_precision()const{
|
||||
return mpfi_get_prec(mpfi());
|
||||
return (_left.get_precision()>_right.get_precision()?
|
||||
(Gmpfi::Precision_type)_left.get_precision():
|
||||
(Gmpfi::Precision_type)_right.get_precision());
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
@ -403,89 +456,101 @@ Gmpfi Gmpfi::operator+()const{
|
|||
|
||||
inline
|
||||
Gmpfi Gmpfi::operator-()const{
|
||||
Gmpfi result(0,get_precision());
|
||||
mpfi_neg(result.mpfi(),mpfi());
|
||||
return result;
|
||||
mpfi_t result;
|
||||
mpfi_init2(result,get_precision());
|
||||
mpfi_neg(result,mpfi());
|
||||
return Gmpfi(result);
|
||||
}
|
||||
|
||||
// CGAL_GMPFI_BALANCE_ENDPOINTS checks if both endpoints of the interval have
|
||||
// CGAL_GMPFI_BALANCE_ENDPOINTS checks if both bounds of the interval have
|
||||
// the same precision. If not, it rounds the one with the smallest
|
||||
// precision.
|
||||
#define CGAL_GMPFI_BALANCE_ENDPOINTS \
|
||||
if(mpfr_get_prec(left_mpfr())<mpfr_get_prec(right_mpfr())){\
|
||||
mpfr_round_prec(&(mpfi()->left), \
|
||||
GMP_RNDD, \
|
||||
mpfr_get_prec(right_mpfr())); \
|
||||
if(_left.get_precision()<_right.get_precision()){ \
|
||||
_left=Gmpfr(_left,_right.get_precision()); \
|
||||
}else{ \
|
||||
if(mpfr_get_prec(left_mpfr())>mpfr_get_prec(right_mpfr())){\
|
||||
mpfr_round_prec(&(mpfi()->right), \
|
||||
GMP_RNDU, \
|
||||
mpfr_get_prec(left_mpfr())); \
|
||||
if(_right.get_precision()<_left.get_precision()){ \
|
||||
_right=Gmpfr(_right,_left.get_precision()); \
|
||||
} \
|
||||
}
|
||||
}; \
|
||||
CGAL_assertion_msg(_left.get_precision()==_right.get_precision(), \
|
||||
"error balancing bounds precision");
|
||||
|
||||
// CGAL_GMPFI_OBJECT_BINARY_OPERATOR defines an overloaded binary operator of
|
||||
// the Gmpfi class, where the operated object belongs to another class,
|
||||
// CGAL_GMPFI_OBJECT_BINARY_OPERATOR defines an overloaded binary operator
|
||||
// of the Gmpfi class, where the operated object belongs to another class,
|
||||
// which represents a point (as opposition to an interval). The operation
|
||||
// will be performed using the biggest precision of the endpoints of this
|
||||
// Gmpfi object. That means that if endpoints have different precision, one
|
||||
// of them (the one with the biggest precision) will be rounded. This is
|
||||
// will be performed using the biggest precision of the bounds of this
|
||||
// Gmpfi object. That means that if bounds have different precision, one
|
||||
// of them (the one with the smallest precision) will be rounded. This is
|
||||
// not a problem when the object is not unique, since a new Gmpfi object
|
||||
// will be created with the endpoints having the correct precision.
|
||||
// will be created with the bounds having the correct precision.
|
||||
#define CGAL_GMPFI_OBJECT_BINARY_OPERATOR(_op,_class,_member,_fun) \
|
||||
inline \
|
||||
Gmpfi& Gmpfi::_op(const _class &b){ \
|
||||
if(unique()){ \
|
||||
if(is_unique()){ \
|
||||
CGAL_GMPFI_BALANCE_ENDPOINTS \
|
||||
_fun(mpfi(),mpfi(),b._member); \
|
||||
gather_bounds(); \
|
||||
}else{ \
|
||||
Gmpfi result(0,get_precision()); \
|
||||
_fun(result.mpfi(),mpfi(),b._member); \
|
||||
swap(result); \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,get_precision()); \
|
||||
_fun(result,mpfi(),b._member); \
|
||||
Gmpfi r(result); \
|
||||
swap(r); \
|
||||
} \
|
||||
return(*this); \
|
||||
}
|
||||
|
||||
// CGAL_GMPFI_GMPFI_BINARY_OPERATOR defines an overloaded binary operator of
|
||||
// the Gmpfi class, where the operated object is also a Gmpfi object.
|
||||
// The operation will be performed using the biggest precision of the
|
||||
// endpoints of both intervals. The endpoints of target object will be
|
||||
// rounded accordingly before the operation.
|
||||
// CGAL_GMPFI_GMPFI_BINARY_OPERATOR defines an overloaded binary operator
|
||||
// of the Gmpfi class, where both operands are Gmpfi objects. The
|
||||
// operation will be performed using the biggest precision of the bounds
|
||||
// of both intervals. The bounds of target object will be rounded
|
||||
// accordingly before the operation.
|
||||
#define CGAL_GMPFI_GMPFI_BINARY_OPERATOR(_op,_fun) \
|
||||
inline \
|
||||
Gmpfi& Gmpfi::_op(const Gmpfi &fi){ \
|
||||
if(unique()){ \
|
||||
if(is_unique()){ \
|
||||
if(get_precision()<fi.get_precision()){ \
|
||||
mpfi_round_prec(mpfi(),fi.get_precision()); \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,fi.get_precision()); \
|
||||
_fun(result,mpfi(),fi.mpfi()); \
|
||||
Gmpfi r(result); \
|
||||
swap(r); \
|
||||
}else{ \
|
||||
CGAL_GMPFI_BALANCE_ENDPOINTS \
|
||||
_fun(mpfi(),mpfi(),fi.mpfi()); \
|
||||
gather_bounds(); \
|
||||
} \
|
||||
_fun(mpfi(),mpfi(),fi.mpfi()); \
|
||||
}else{ \
|
||||
Gmpfi result(0, \
|
||||
get_precision()<fi.get_precision()? \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result, \
|
||||
get_precision()<fi.get_precision()? \
|
||||
fi.get_precision(): \
|
||||
get_precision()); \
|
||||
_fun(result.mpfi(),mpfi(),fi.mpfi()); \
|
||||
swap(result); \
|
||||
_fun(result,mpfi(),fi.mpfi()); \
|
||||
Gmpfi r(result); \
|
||||
swap(r); \
|
||||
} \
|
||||
return(*this); \
|
||||
}
|
||||
|
||||
// CGAL_GMPFI_TYPE_BINARY_OPERATOR defines an overloaded binary operator of
|
||||
// the Gmpfi class, where the operated belongs to a c++ type. Precision of
|
||||
// the operation is defined in the same manner that in
|
||||
// the Gmpfi class, where the operated number belongs to a c++ type.
|
||||
// Precision of the operation is defined in the same manner that in
|
||||
// CGAL_GMPFI_OBJECT_BINARY_OPERATOR.
|
||||
#define CGAL_GMPFI_TYPE_BINARY_OPERATOR(_op,_type,_fun) \
|
||||
inline \
|
||||
Gmpfi& Gmpfi::_op(_type x){ \
|
||||
if(unique()){ \
|
||||
if(is_unique()){ \
|
||||
CGAL_GMPFI_BALANCE_ENDPOINTS \
|
||||
_fun(mpfi(),mpfi(),x); \
|
||||
gather_bounds(); \
|
||||
}else{ \
|
||||
Gmpfi result(0,get_precision()); \
|
||||
_fun(result.mpfi(),mpfi(),x); \
|
||||
swap(result); \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,get_precision()); \
|
||||
_fun(result,mpfi(),x); \
|
||||
Gmpfi r(result); \
|
||||
swap(r); \
|
||||
} \
|
||||
return *this; \
|
||||
}
|
||||
|
|
@ -536,9 +601,11 @@ CGAL_GMPFI_OBJECT_BINARY_OPERATOR(operator/=,Gmpq,mpq(),mpfi_div_q)
|
|||
#define CGAL_GMPFI_ARITHMETIC_FUNCTION(_name,_fun) \
|
||||
inline \
|
||||
Gmpfi Gmpfi::_name (Gmpfi::Precision_type p)const{ \
|
||||
Gmpfi result(0,p); \
|
||||
_fun(result.mpfi(),mpfi()); \
|
||||
return result; \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,p); \
|
||||
_fun(result,mpfi()); \
|
||||
return Gmpfi(result); \
|
||||
}
|
||||
|
||||
CGAL_GMPFI_ARITHMETIC_FUNCTION(abs,mpfi_abs)
|
||||
|
|
@ -547,19 +614,23 @@ CGAL_GMPFI_ARITHMETIC_FUNCTION(sqrt,mpfi_sqrt)
|
|||
inline
|
||||
Gmpfi Gmpfi::cbrt(Gmpfi::Precision_type p)const{
|
||||
// MPFI does not provide a cubic root function
|
||||
Gmpfi result(0,p);
|
||||
mpfr_cbrt(&(result.mpfi())->left,left_mpfr(),GMP_RNDD);
|
||||
mpfr_cbrt(&(result.mpfi())->right,right_mpfr(),GMP_RNDU);
|
||||
return result;
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfi_t result;
|
||||
mpfi_init2(result,p);
|
||||
mpfr_cbrt(&result->left,left_mpfr(),GMP_RNDD);
|
||||
mpfr_cbrt(&result->right,right_mpfr(),GMP_RNDU);
|
||||
return Gmpfi(result);
|
||||
}
|
||||
|
||||
inline
|
||||
Gmpfi Gmpfi::kthroot(int k,Gmpfi::Precision_type p)const{
|
||||
// MPFI does not provide k-th root functions
|
||||
Gmpfi result(0,p);
|
||||
mpfr_root(&(result.mpfi())->left,left_mpfr(),k,GMP_RNDD);
|
||||
mpfr_root(&(result.mpfi())->right,right_mpfr(),k,GMP_RNDU);
|
||||
return result;
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfi_t result;
|
||||
mpfi_init2(result,p);
|
||||
mpfr_root(&result->left,left_mpfr(),k,GMP_RNDD);
|
||||
mpfr_root(&result->right,right_mpfr(),k,GMP_RNDU);
|
||||
return Gmpfi(result);
|
||||
}
|
||||
|
||||
CGAL_GMPFI_ARITHMETIC_FUNCTION(square,mpfi_sqr)
|
||||
|
|
@ -622,10 +693,10 @@ bool Gmpfi::is_number()const{
|
|||
|
||||
inline
|
||||
Uncertain<Sign> Gmpfi::sign()const{
|
||||
int s_left=mpfr_sgn(left_mpfr());
|
||||
if(s_left>0)
|
||||
int leftsign=mpfr_sgn(left_mpfr());
|
||||
if(leftsign>0)
|
||||
return POSITIVE;
|
||||
if(s_left==0){
|
||||
if(leftsign==0){
|
||||
if(mpfr_zero_p(right_mpfr())!=0)
|
||||
return ZERO;
|
||||
else
|
||||
|
|
@ -677,7 +748,7 @@ Uncertain<bool> Gmpfi::is_square(Gmpfi &y)const{
|
|||
inline
|
||||
Uncertain<bool> Gmpfi::divides(const Gmpfi &n,Gmpfi &c,Gmpfi::Precision_type p
|
||||
)const{
|
||||
if(mpfr_zero_p(&mpfi()->left)!=0 && mpfr_zero_p(&mpfi()->right)!=0)
|
||||
if(mpfr_zero_p(left_mpfr())!=0 && mpfr_zero_p(right_mpfr())!=0)
|
||||
return false;
|
||||
if(mpfi_has_zero(mpfi())!=0)
|
||||
return Uncertain<bool>::indeterminate();
|
||||
|
|
@ -709,7 +780,7 @@ std::pair<double,double> Gmpfi::to_interval()const{
|
|||
double d_low=mpfr_get_d(left_mpfr(),GMP_RNDD);
|
||||
double d_upp=mpfr_get_d(right_mpfr(),GMP_RNDU);
|
||||
CGAL_assertion(std::numeric_limits<double>::has_infinity);
|
||||
// if an endpoint is finite and its double is infinity, we overflow
|
||||
// if a bound is finite and its double is infinity, we overflow
|
||||
if(mpfr_inf_p(left_mpfr())==0&&
|
||||
d_low==std::numeric_limits<double>::infinity())
|
||||
mpfr_set_underflow();
|
||||
|
|
|
|||
|
|
@ -42,9 +42,10 @@
|
|||
if(!p) \
|
||||
p=CGAL_GMPFI_PREC_2(a,b); \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
Gmpfi result(0,p); \
|
||||
_fun(result.mpfi(),a.mpfi(),b.mpfi()); \
|
||||
return result; \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,p); \
|
||||
_fun(result,a.mpfi(),b.mpfi()); \
|
||||
return Gmpfi(result); \
|
||||
}
|
||||
|
||||
// CGAL_GMPFI_COMMUTATIVE_OP defines a commutative arithmetic operation
|
||||
|
|
@ -55,18 +56,20 @@
|
|||
if(!p) \
|
||||
p=CGAL_GMPFI_PREC(a); \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
Gmpfi result(0,p); \
|
||||
_fun(result.mpfi(),a.mpfi(),_member); \
|
||||
return result; \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,p); \
|
||||
_fun(result,a.mpfi(),_member); \
|
||||
return Gmpfi(result); \
|
||||
} \
|
||||
inline \
|
||||
Gmpfi Gmpfi::_name (_type b,const Gmpfi &a,Gmpfi::Precision_type p){ \
|
||||
if(!p) \
|
||||
p=CGAL_GMPFI_PREC(a); \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
Gmpfi result(0,p); \
|
||||
_fun(result.mpfi(),a.mpfi(),_member); \
|
||||
return result; \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,p); \
|
||||
_fun(result,a.mpfi(),_member); \
|
||||
return Gmpfi(result); \
|
||||
}
|
||||
|
||||
// CGAL_GMPFI_NONCOMMUTATIVE_OP defines a non-commutative arithmetic
|
||||
|
|
@ -77,18 +80,20 @@
|
|||
if(!p) \
|
||||
p=CGAL_GMPFI_PREC(a); \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
Gmpfi result(0,p); \
|
||||
_fun1(result.mpfi(),a.mpfi(),_member); \
|
||||
return result; \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,p); \
|
||||
_fun1(result,a.mpfi(),_member); \
|
||||
return Gmpfi(result); \
|
||||
} \
|
||||
inline \
|
||||
Gmpfi Gmpfi::_name (_type b,const Gmpfi &a,Gmpfi::Precision_type p){ \
|
||||
if(!p) \
|
||||
p=CGAL_GMPFI_PREC(a); \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
Gmpfi result(0,p); \
|
||||
_fun2(result.mpfi(),_member,a.mpfi()); \
|
||||
return result; \
|
||||
mpfi_t result; \
|
||||
mpfi_init2(result,p); \
|
||||
_fun2(result,_member,a.mpfi()); \
|
||||
return Gmpfi(result); \
|
||||
}
|
||||
|
||||
CGAL_GMPFI_OP_GMPFI(add,mpfi_add)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <CGAL/Handle_for.h>
|
||||
#include <CGAL/GMP/Gmpz_type.h>
|
||||
#include <CGAL/GMP/Gmpzf_type.h>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <CGAL/Uncertain.h>
|
||||
#include <CGAL/ipower.h>
|
||||
|
|
@ -98,7 +97,7 @@ class Gmpfr:
|
|||
|
||||
typedef Handle_for<Gmpfr_rep> Base;
|
||||
|
||||
static inline Uncertain<mp_rnd_t> _gmp_rnd(std::float_round_style r){
|
||||
static Uncertain<mp_rnd_t> _gmp_rnd(std::float_round_style r){
|
||||
switch(r){
|
||||
case std::round_toward_infinity: return GMP_RNDU;
|
||||
case std::round_toward_neg_infinity: return GMP_RNDD;
|
||||
|
|
@ -108,7 +107,7 @@ class Gmpfr:
|
|||
}
|
||||
};
|
||||
|
||||
static inline std::float_round_style _cgal_rnd(mp_rnd_t r){
|
||||
static std::float_round_style _cgal_rnd(mp_rnd_t r){
|
||||
switch(r){
|
||||
case GMP_RNDU: return std::round_toward_infinity;
|
||||
case GMP_RNDD: return std::round_toward_neg_infinity;
|
||||
|
|
@ -124,7 +123,6 @@ class Gmpfr:
|
|||
|
||||
// access
|
||||
|
||||
inline
|
||||
mpfr_srcptr fr()const{
|
||||
#ifdef CGAL_GMPFR_NO_REFCOUNT
|
||||
return floating_point_number;
|
||||
|
|
@ -133,7 +131,6 @@ class Gmpfr:
|
|||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
mpfr_ptr fr(){
|
||||
#ifdef CGAL_GMPFR_NO_REFCOUNT
|
||||
return floating_point_number;
|
||||
|
|
@ -142,7 +139,6 @@ class Gmpfr:
|
|||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
void dont_clear_on_destruction(){
|
||||
#ifdef CGAL_GMPFR_NO_REFCOUNT
|
||||
clear_on_destruction=false;
|
||||
|
|
@ -151,6 +147,14 @@ class Gmpfr:
|
|||
#endif
|
||||
}
|
||||
|
||||
bool is_unique(){
|
||||
#ifdef CGAL_GMPFR_NO_REFCOUNT
|
||||
return true;
|
||||
#else
|
||||
return unique();
|
||||
#endif
|
||||
}
|
||||
|
||||
// construction
|
||||
|
||||
Gmpfr(){
|
||||
|
|
@ -158,15 +162,13 @@ class Gmpfr:
|
|||
}
|
||||
|
||||
Gmpfr(mpfr_srcptr f){
|
||||
//mpfr_custom_init_set(
|
||||
// fr(),
|
||||
// mpfr_custom_get_kind(f),
|
||||
// mpfr_custom_get_exp(f),
|
||||
// mpfr_get_prec(f),
|
||||
// mpfr_custom_get_mantissa(f));
|
||||
//dont_clear_on_destruction();
|
||||
mpfr_init2(fr(),mpfr_get_prec(f));
|
||||
mpfr_set(fr(),f,GMP_RNDN);
|
||||
mpfr_custom_init_set(
|
||||
fr(),
|
||||
mpfr_custom_get_kind(f),
|
||||
mpfr_custom_get_exp(f),
|
||||
mpfr_get_prec(f),
|
||||
mpfr_custom_get_mantissa(f));
|
||||
dont_clear_on_destruction();
|
||||
CGAL_assertion((mpfr_nan_p(f)!=0 && mpfr_nan_p(fr())!=0) ||
|
||||
(mpfr_unordered_p(f,fr())==0 &&
|
||||
mpfr_equal_p(f,fr())!=0));
|
||||
|
|
@ -175,16 +177,45 @@ class Gmpfr:
|
|||
Gmpfr(mpfr_srcptr f,
|
||||
std::float_round_style r,
|
||||
Gmpfr::Precision_type p=Gmpfr::get_default_precision()){
|
||||
mpfr_init2(fr(),p);
|
||||
mpfr_set(fr(),f,_gmp_rnd(r));
|
||||
CGAL_assertion(mpfr_get_prec(fr())<mpfr_get_prec(f) ||
|
||||
mpfr_equal_p(fr(),f)!=0);
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
if(p==mpfr_get_prec(f)){
|
||||
mpfr_custom_init_set(
|
||||
fr(),
|
||||
mpfr_custom_get_kind(f),
|
||||
mpfr_custom_get_exp(f),
|
||||
mpfr_get_prec(f),
|
||||
mpfr_custom_get_mantissa(f));
|
||||
dont_clear_on_destruction();
|
||||
CGAL_assertion((mpfr_nan_p(f)!=0&&mpfr_nan_p(fr())!=0)||
|
||||
(mpfr_unordered_p(f,fr())==0&&
|
||||
mpfr_equal_p(f,fr())!=0));
|
||||
}else{
|
||||
mpfr_init2(fr(),p);
|
||||
mpfr_set(fr(),f,_gmp_rnd(r));
|
||||
CGAL_assertion(mpfr_get_prec(fr())<mpfr_get_prec(f)||
|
||||
mpfr_equal_p(fr(),f)!=0);
|
||||
}
|
||||
}
|
||||
|
||||
Gmpfr(mpfr_srcptr f,Gmpfr::Precision_type p){
|
||||
mpfr_init2(fr(),p);
|
||||
mpfr_set(fr(),f,mpfr_get_default_rounding_mode());
|
||||
CGAL_assertion(p<mpfr_get_prec(f) || mpfr_equal_p(fr(),f)!=0);
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
if(p==mpfr_get_prec(f)){
|
||||
mpfr_custom_init_set(
|
||||
fr(),
|
||||
mpfr_custom_get_kind(f),
|
||||
mpfr_custom_get_exp(f),
|
||||
mpfr_get_prec(f),
|
||||
mpfr_custom_get_mantissa(f));
|
||||
dont_clear_on_destruction();
|
||||
CGAL_assertion((mpfr_nan_p(f)!=0&&mpfr_nan_p(fr())!=0)||
|
||||
(mpfr_unordered_p(f,fr())==0&&
|
||||
mpfr_equal_p(f,fr())!=0));
|
||||
}else{
|
||||
mpfr_init2(fr(),p);
|
||||
mpfr_set(fr(),f,mpfr_get_default_rounding_mode());
|
||||
CGAL_assertion(p<mpfr_get_prec(f)||
|
||||
mpfr_equal_p(fr(),f)!=0);
|
||||
}
|
||||
}
|
||||
|
||||
Gmpfr(Gmpzf f,
|
||||
|
|
@ -222,13 +253,14 @@ class Gmpfr:
|
|||
Gmpfr(std::pair<Gmpz,long> intexp,
|
||||
std::float_round_style r=Gmpfr::get_default_rndmode(),
|
||||
Gmpfr::Precision_type p=Gmpfr::get_default_precision()){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfr_init2(fr(),p);
|
||||
mpfr_set_z(fr(),intexp.first.mpz(),_gmp_rnd(r));
|
||||
mpfr_mul_2si(fr(),fr(),intexp.second,_gmp_rnd(r));
|
||||
}
|
||||
|
||||
Gmpfr(std::pair<Gmpz,long> intexp,
|
||||
Gmpfr::Precision_type p){
|
||||
Gmpfr(std::pair<Gmpz,long> intexp,Gmpfr::Precision_type p){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
mpfr_init2(fr(),p);
|
||||
mpfr_set_z(fr(),
|
||||
intexp.first.mpz(),
|
||||
|
|
@ -243,10 +275,12 @@ class Gmpfr:
|
|||
Gmpfr(_type x, \
|
||||
std::float_round_style r, \
|
||||
Gmpfr::Precision_type p=Gmpfr::get_default_precision()){ \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
mpfr_init2(fr(),p); \
|
||||
_fun(fr(),x,_gmp_rnd(r)); \
|
||||
} \
|
||||
Gmpfr(_type x,Gmpfr::Precision_type p){ \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
mpfr_init2(fr(),p); \
|
||||
_fun(fr(),x,mpfr_get_default_rounding_mode()); \
|
||||
} \
|
||||
|
|
@ -268,10 +302,12 @@ class Gmpfr:
|
|||
Gmpfr(const _class &x, \
|
||||
std::float_round_style r, \
|
||||
Gmpfr::Precision_type p=Gmpfr::get_default_precision()){ \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
mpfr_init2(fr(),p); \
|
||||
_fun(fr(),x._member,_gmp_rnd(r)); \
|
||||
} \
|
||||
Gmpfr(const _class &x,Gmpfr::Precision_type p){ \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
mpfr_init2(fr(),p); \
|
||||
_fun(fr(),x._member,mpfr_get_default_rounding_mode()); \
|
||||
} \
|
||||
|
|
@ -300,13 +336,15 @@ class Gmpfr:
|
|||
}
|
||||
#endif
|
||||
|
||||
Gmpfr(
|
||||
const Gmpfr &a,
|
||||
Gmpfr(const Gmpfr &a,
|
||||
std::float_round_style r,
|
||||
Gmpfr::Precision_type p=Gmpfr::get_default_precision()){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
#ifndef CGAL_GMPFR_NO_REFCOUNT
|
||||
if(p==a.get_precision()){
|
||||
Gmpfr temp(a);
|
||||
// we use dont_clear_on_destruction because the
|
||||
// mpfr_t pointed to by fr() was never initialized
|
||||
dont_clear_on_destruction();
|
||||
swap(temp);
|
||||
}else
|
||||
|
|
@ -318,9 +356,12 @@ class Gmpfr:
|
|||
}
|
||||
|
||||
Gmpfr(const Gmpfr &a,Gmpfr::Precision_type p){
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
#ifndef CGAL_GMPFR_NO_REFCOUNT
|
||||
if(p==a.get_precision()){
|
||||
Gmpfr temp(a);
|
||||
// we use dont_clear_on_destruction because the
|
||||
// mpfr_t pointed to by fr() was never initialized
|
||||
dont_clear_on_destruction();
|
||||
swap(temp);
|
||||
}else
|
||||
|
|
@ -334,7 +375,8 @@ class Gmpfr:
|
|||
// default rounding mode
|
||||
|
||||
static std::float_round_style get_default_rndmode();
|
||||
static std::float_round_style set_default_rndmode(std::float_round_style);
|
||||
static std::float_round_style
|
||||
set_default_rndmode(std::float_round_style);
|
||||
|
||||
// default precision
|
||||
|
||||
|
|
@ -377,7 +419,9 @@ class Gmpfr:
|
|||
#undef CGAL_GMPFR_DECLARE_OPERATORS
|
||||
|
||||
#define CGAL_GMPFR_DECLARE_STATIC_FUNCTION(_f,_t1,_t2) \
|
||||
static Gmpfr _f (_t1,_t2,std::float_round_style=Gmpfr::get_default_rndmode()); \
|
||||
static Gmpfr _f (_t1, \
|
||||
_t2, \
|
||||
std::float_round_style=Gmpfr::get_default_rndmode()); \
|
||||
static Gmpfr _f (_t1, \
|
||||
_t2, \
|
||||
Gmpfr::Precision_type, \
|
||||
|
|
@ -483,6 +527,7 @@ Gmpfr::Precision_type Gmpfr::get_precision()const{
|
|||
|
||||
inline
|
||||
Gmpfr Gmpfr::round(Gmpfr::Precision_type p,std::float_round_style r)const{
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
return Gmpfr(*this,r,p);
|
||||
}
|
||||
|
||||
|
|
@ -758,12 +803,14 @@ CGAL_GMPFR_OBJECT_BINARY_OPERATOR(operator/=,Gmpz,mpz(),mpfr_div_z)
|
|||
#include <CGAL/GMP/Gmpfr_type_static.h>
|
||||
|
||||
#define CGAL_GMPFR_ARITHMETIC_FUNCTION(_name,_fun) \
|
||||
inline Gmpfr Gmpfr::_name (std::float_round_style r)const{ \
|
||||
inline \
|
||||
Gmpfr Gmpfr::_name (std::float_round_style r)const{ \
|
||||
Gmpfr result(0,CGAL_GMPFR_MEMBER_PREC()); \
|
||||
_fun(result.fr(),fr(),_gmp_rnd(r)); \
|
||||
return result; \
|
||||
} \
|
||||
inline Gmpfr Gmpfr::_name (Gmpfr::Precision_type p, \
|
||||
inline \
|
||||
Gmpfr Gmpfr::_name (Gmpfr::Precision_type p, \
|
||||
std::float_round_style r)const{ \
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX); \
|
||||
Gmpfr result(0,p); \
|
||||
|
|
@ -775,13 +822,15 @@ CGAL_GMPFR_ARITHMETIC_FUNCTION(abs,mpfr_abs)
|
|||
CGAL_GMPFR_ARITHMETIC_FUNCTION(sqrt,mpfr_sqrt)
|
||||
CGAL_GMPFR_ARITHMETIC_FUNCTION(cbrt,mpfr_cbrt)
|
||||
|
||||
inline Gmpfr Gmpfr::kthroot(int k,std::float_round_style r)const{
|
||||
inline
|
||||
Gmpfr Gmpfr::kthroot(int k,std::float_round_style r)const{
|
||||
Gmpfr result(0,CGAL_GMPFR_MEMBER_PREC());
|
||||
mpfr_root(result.fr(),fr(),k,_gmp_rnd(r));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Gmpfr Gmpfr::kthroot(int k,
|
||||
inline
|
||||
Gmpfr Gmpfr::kthroot(int k,
|
||||
Gmpfr::Precision_type p,
|
||||
std::float_round_style r)const{
|
||||
CGAL_assertion(p>=MPFR_PREC_MIN&&p<=MPFR_PREC_MAX);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,17 @@ int test_precision(){
|
|||
return 0;
|
||||
}
|
||||
|
||||
int test_refcount(){
|
||||
CGAL::Gmpq A("6420587669/17179869184");
|
||||
CGAL::Gmpfi f(A,20);
|
||||
CGAL::Gmpfr i=f.inf();
|
||||
assert(!i.is_unique());
|
||||
i*=2;
|
||||
assert(i!=f.inf());
|
||||
assert(i.is_unique());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(){
|
||||
typedef CGAL::Gmpfi NT;
|
||||
typedef CGAL::Field_with_kth_root_tag Tag;
|
||||
|
|
@ -153,6 +164,12 @@ int main(){
|
|||
// TODO: missing tests for conversion functions
|
||||
// to_double, to_interval, to_double_exp, to_interval_exp
|
||||
|
||||
#ifndef CGAL_GMPFR_NO_REFCOUNT
|
||||
_TEST("endpoint reference counting",test_refcount())
|
||||
#else
|
||||
std::cerr<<"endpoint reference counting was not tested"<<std::endl;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue