diff --git a/Number_types/doc_tex/NumberTypeSupport_ref/Gmpfr.tex b/Number_types/doc_tex/NumberTypeSupport_ref/Gmpfr.tex index 9f3c13c56f5..f5f8565bdab 100644 --- a/Number_types/doc_tex/NumberTypeSupport_ref/Gmpfr.tex +++ b/Number_types/doc_tex/NumberTypeSupport_ref/Gmpfr.tex @@ -19,7 +19,7 @@ can be set to any of the four rounding modes (initially, it is set to nearest). To specify rounding modes for operations, the type used is \ccc{std::float_round_style}. -This type is \ccc{ImplicitInteroperable} with \ccc{Gmpz}, \ccc{Gmpq}, +This type is \ccc{ImplicitInteroperable} with \ccc{Gmpz}, %\ccc{Gmpq}, \verb-long-, \verb-unsigned long-, \verb-int-, \verb-double- and \verb-long double-. @@ -71,8 +71,10 @@ This type is \ccc{ImplicitInteroperable} with \ccc{Gmpz}, \ccc{Gmpq}, \ccConstructor{Gmpfr(const Gmpz &z);} {Creates a MPFR number, initialized with the value of \ccc{z}.} -\ccConstructor{Gmpfr(const Gmpq &q);} - {Creates a MPFR number, initialized with the value of \ccc{q}.} +%-------------------------------------------------- +% \ccConstructor{Gmpfr(const Gmpq &q);} +% {Creates a MPFR number, initialized with the value of \ccc{q}.} +%-------------------------------------------------- \ccConstructor{Gmpfr(const Gmpzf &z);} {Creates a MPFR number, initialized with the value of \ccc{z}.} @@ -197,7 +199,8 @@ as the maximum of the operands precision and the default precision. The second operand of the former operations can be a \verb=Gmpfr=, \verb=int=, \verb=long=, \verb=unsigned=, \verb=unsigned long=, -\verb=Gmpz= or \verb=Gmpq=. The precision of an operation between a +%\verb=Gmpz= or \verb=Gmpq=. The precision of an operation between a +or \verb=Gmpz=. The precision of an operation between a \ccc{Gmpfr} and a number of another type is defined as the maximum between the number's precision and the default precision. @@ -289,9 +292,11 @@ Other arithmetic functions provided by the class are: is not necessarily the smallest possible value of \(m\) (that is, it might be that \(2|m\)).} -\ccMethod{Gmpq to_fraction();} - {Returns a \ccc{Gmpq} with the same value of \ccVar. This - conversion is exact.} +%-------------------------------------------------- +% \ccMethod{Gmpq to_fraction();} +% {Returns a \ccc{Gmpq} with the same value of \ccVar. This +% conversion is exact.} +%-------------------------------------------------- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -301,7 +306,7 @@ Other arithmetic functions provided by the class are: Comparison operators \verb-==-, \verb-!=-, \verb->-, \verb-<-, \verb->=- \ and \verb-<=- \ are also overloaded. A \ccc{Gmpfr} can be compared -with other \ccc{Gmpfr}, as well as with a \ccc{Gmpz}, \ccc{Gmpq}, +with other \ccc{Gmpfr}, as well as with a \ccc{Gmpz}, %\ccc{Gmpq}, \verb=long=, \verb=unsigned long=, \verb=int=, \verb=double= \ or \verb=long double=. It is worth noting that the numbers are never converted nor rounded before comparison. In the case where one of the diff --git a/Number_types/include/CGAL/GMP/Gmpfr_type.h b/Number_types/include/CGAL/GMP/Gmpfr_type.h index a7b5c76a65c..0b31c8ebcaf 100644 --- a/Number_types/include/CGAL/GMP/Gmpfr_type.h +++ b/Number_types/include/CGAL/GMP/Gmpfr_type.h @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2009 Inria Lorraine (France). All rights reserved. +// Copyright (c) 2007-2010 Inria Lorraine (France). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -62,10 +61,6 @@ bool operator<(const Gmpfr&,const Gmpz&); bool operator>(const Gmpfr&,const Gmpz&); bool operator==(const Gmpfr&,const Gmpz&); -bool operator<(const Gmpfr&,const Gmpq&); -bool operator>(const Gmpfr&,const Gmpq&); -bool operator==(const Gmpfr&,const Gmpq&); - struct Gmpfr_rep{ mpfr_t floating_point_number; bool clear_on_destruction; @@ -96,9 +91,8 @@ class Gmpfr: boost::ordered_euclidian_ring_operators2 > > > > > > > + boost::ordered_euclidian_ring_operators2 > > > > > > { private: @@ -259,7 +253,6 @@ class Gmpfr: _GMPFR_CONSTRUCTOR_FROM_TYPE(double,mpfr_set_d); _GMPFR_CONSTRUCTOR_FROM_TYPE(long double,mpfr_set_ld); _GMPFR_CONSTRUCTOR_FROM_OBJECT(Gmpz,mpz(),mpfr_set_z); - _GMPFR_CONSTRUCTOR_FROM_OBJECT(Gmpq,mpq(),mpfr_set_q); #undef _GMPFR_CONSTRUCTOR_FROM_TYPE #undef _GMPFR_CONSTRUCTOR_FROM_OBJECT @@ -353,7 +346,6 @@ class Gmpfr: _GMPFR_DECLARE_OPERATORS(unsigned long) _GMPFR_DECLARE_OPERATORS(int) _GMPFR_DECLARE_OPERATORS(const Gmpz&) - _GMPFR_DECLARE_OPERATORS(const Gmpq&) #undef _GMPFR_DECLARE_OPERATORS @@ -375,7 +367,6 @@ class Gmpfr: _GMPFR_DECLARE_STATIC_FUNCTIONS(unsigned long) _GMPFR_DECLARE_STATIC_FUNCTIONS(int) _GMPFR_DECLARE_STATIC_FUNCTIONS(const Gmpz&) - _GMPFR_DECLARE_STATIC_FUNCTIONS(const Gmpq&) #undef _GMPFR_DECLARE_STATIC_FUNCTION #undef _GMPFR_DECLARE_STATIC_FUNCTIONS @@ -418,7 +409,6 @@ class Gmpfr: to_double_exp(std::float_round_style=Gmpfr::get_default_rndmode())const; std::pair,long> to_interval_exp()const; std::pair to_integer_exp()const; - Gmpq to_fraction()const; }; @@ -731,11 +721,6 @@ _GMPFR_OBJECT_BINARY_OPERATOR(operator-=,Gmpz,mpz(),mpfr_sub_z) _GMPFR_OBJECT_BINARY_OPERATOR(operator*=,Gmpz,mpz(),mpfr_mul_z) _GMPFR_OBJECT_BINARY_OPERATOR(operator/=,Gmpz,mpz(),mpfr_div_z) -_GMPFR_OBJECT_BINARY_OPERATOR(operator+=,Gmpq,mpq(),mpfr_add_q) -_GMPFR_OBJECT_BINARY_OPERATOR(operator-=,Gmpq,mpq(),mpfr_sub_q) -_GMPFR_OBJECT_BINARY_OPERATOR(operator*=,Gmpq,mpq(),mpfr_mul_q) -_GMPFR_OBJECT_BINARY_OPERATOR(operator/=,Gmpq,mpq(),mpfr_div_q) - #undef _GMPFR_OBJECT_BINARY_OPERATOR #undef _GMPFR_GMPFR_BINARY_OPERATOR #undef _GMPFR_TYPE_BINARY_OPERATOR @@ -896,29 +881,6 @@ std::pair Gmpfr::to_integer_exp()const{ return std::make_pair(z,e); } -inline -Gmpq Gmpfr::to_fraction()const{ - std::pair p=this->to_integer_exp(); - Gmpq q(p.first); - CGAL_assertion(mpz_cmp(p.first.mpz(),mpq_numref(q.mpq()))==0); - CGAL_assertion(mpz_cmp_ui(mpq_denref(q.mpq()),(unsigned long)1)==0); - if(p.second<0){ - mpz_mul_2exp(mpq_denref(q.mpq()), - mpq_denref(q.mpq()), - (unsigned long)(-p.second)); - }else{ - mpz_mul_2exp(mpq_numref(q.mpq()), - mpq_numref(q.mpq()), - (unsigned long)(p.second)); - } - mpq_canonicalize(q.mpq()); - CGAL_assertion_msg(mpz_sizeinbase(mpq_denref(q.mpq()),2)== - mpz_scan1(mpq_denref(q.mpq()),0)+1, - "denominator is not a power of 2"); - CGAL_assertion_msg(mpfr_cmp_q(fr(),q.mpq())==0,"conversion error"); - return q; -} - // input/output @@ -1154,21 +1116,6 @@ bool operator==(const Gmpfr &a,const Gmpz &b){ return !mpfr_cmp_z(a.fr(),b.mpz()); } -inline -bool operator<(const Gmpfr &a,const Gmpq &b){ - return(mpfr_cmp_q(a.fr(),b.mpq())<0); -} - -inline -bool operator>(const Gmpfr &a,const Gmpq &b){ - return(mpfr_cmp_q(a.fr(),b.mpq())>0); -} - -inline -bool operator==(const Gmpfr &a,const Gmpq &b){ - return !mpfr_cmp_q(a.fr(),b.mpq()); -} - inline Gmpfr min BOOST_PREVENT_MACRO_SUBSTITUTION(const Gmpfr& x,const Gmpfr& y){ return (x<=y)?x:y; diff --git a/Number_types/include/CGAL/GMP/Gmpfr_type_static.h b/Number_types/include/CGAL/GMP/Gmpfr_type_static.h index b4c2e6650da..79ce6e21de4 100644 --- a/Number_types/include/CGAL/GMP/Gmpfr_type_static.h +++ b/Number_types/include/CGAL/GMP/Gmpfr_type_static.h @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2009 Inria Lorraine (France). All rights reserved. +// Copyright (c) 2007-2010 Inria Lorraine (France). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as @@ -105,11 +105,6 @@ _GMPFR_NONCOMMUTATIVE_OPERATION(sub,const Gmpz&,b.mpz(),mpfr_sub_z) _GMPFR_NONCOMMUTATIVE_OPERATION(mul,const Gmpz&,b.mpz(),mpfr_mul_z) _GMPFR_NONCOMMUTATIVE_OPERATION(div,const Gmpz&,b.mpz(),mpfr_div_z) -_GMPFR_NONCOMMUTATIVE_OPERATION(add,const Gmpq&,b.mpq(),mpfr_add_q) -_GMPFR_NONCOMMUTATIVE_OPERATION(sub,const Gmpq&,b.mpq(),mpfr_sub_q) -_GMPFR_NONCOMMUTATIVE_OPERATION(mul,const Gmpq&,b.mpq(),mpfr_mul_q) -_GMPFR_NONCOMMUTATIVE_OPERATION(div,const Gmpq&,b.mpq(),mpfr_div_q) - #undef _GMPFR_PREC #undef _GMPFR_PREC_2 #undef _GMPFR_OPERATION_GMPFR diff --git a/Number_types/include/CGAL/GMP/Gmpq_type.h b/Number_types/include/CGAL/GMP/Gmpq_type.h index 3361b7fa72a..613ed1381f0 100644 --- a/Number_types/include/CGAL/GMP/Gmpq_type.h +++ b/Number_types/include/CGAL/GMP/Gmpq_type.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -37,9 +38,7 @@ #include #include - CGAL_BEGIN_NAMESPACE -// TODO : add mixed operators with Gmpz. // Wrapper around mpq_t to get the destructor call mpq_clear. // Contrary to mpz_t, there are no mpq_init_set_* functions, @@ -62,9 +61,10 @@ class Gmpq : Handle_for, boost::ordered_field_operators1< Gmpq , boost::ordered_field_operators2< Gmpq, Gmpz + , boost::ordered_field_operators2< Gmpq, Gmpfr , boost::ordered_field_operators2< Gmpq, int , boost::ordered_field_operators2< Gmpq, long - > > > > + > > > > > { typedef Handle_for Base; public: @@ -128,6 +128,28 @@ public: mpq_set_d(mpq(), d); } + Gmpq(Gmpfr f) + { + std::pair intexp=f.to_integer_exp(); + mpq_set_z(mpq(),intexp.first.mpz()); + if(intexp.second>0){ + mpz_mul_2exp(mpq_numref(mpq()), + mpq_denref(mpq()), + (unsigned long)intexp.second); + }else{ + mpz_mul_2exp(mpq_denref(mpq()), + mpq_denref(mpq()), + (unsigned long)intexp.second); + } + // mpq_canonicalize is not needed, because: + // (i) to_integer_exp returns always an odd number + // (ii) the denominator is always a power of 2 + CGAL_assertion_msg(mpz_tstbit(intexp.first.mpz(),0)==1, + "even numerator in conversion Gmpfr->Gmpq"); + CGAL_assertion_msg(mpfr_cmp_q(f.fr(),mpq())==0, + "error in conversion Gmpfr->Gmpq"); + } + Gmpq(const std::string& str, int base = 10) { mpq_set_str(mpq(), str.c_str(), base); @@ -180,30 +202,39 @@ public: CGAL_HISTOGRAM_PROFILER("[Gmpq sizes in log2 scale]", (unsigned) ( ::log(double(size())) / ::log(double(2)) ) ); } - + // Interoperability with int Gmpq& operator+=(int z){return (*this)+= Gmpq(z);} Gmpq& operator-=(int z){return (*this)-= Gmpq(z);} Gmpq& operator*=(int z){return (*this)*= Gmpq(z);} Gmpq& operator/=(int z){return (*this)/= Gmpq(z);} - bool operator==(int z) const {return (*this)== Gmpq(z);} - bool operator< (int z) const {return (*this)< Gmpq(z);} - bool operator> (int z) const {return (*this)> Gmpq(z);} + bool operator==(int z) const {return mpq_cmp_si(mpq(),z,1)==0;} + bool operator< (int z) const {return mpq_cmp_si(mpq(),z,1)<0;} + bool operator> (int z) const {return mpq_cmp_si(mpq(),z,1)>0;} // Interoperability with long Gmpq& operator+=(long z){return (*this)+= Gmpq(z);} Gmpq& operator-=(long z){return (*this)-= Gmpq(z);} Gmpq& operator*=(long z){return (*this)*= Gmpq(z);} Gmpq& operator/=(long z){return (*this)/= Gmpq(z);} - bool operator==(long z) const {return (*this)== Gmpq(z);} - bool operator< (long z) const {return (*this)< Gmpq(z);} - bool operator> (long z) const {return (*this)> Gmpq(z);} + bool operator==(long z) const {return mpq_cmp_si(mpq(),z,1)==0;} + bool operator< (long z) const {return mpq_cmp_si(mpq(),z,1)<0;} + bool operator> (long z) const {return mpq_cmp_si(mpq(),z,1)>0;} + + // Interoperability with Gmpfr + Gmpq& operator+=(const Gmpfr &f){return (*this)+= Gmpq(f);} + Gmpq& operator-=(const Gmpfr &f){return (*this)-= Gmpq(f);} + Gmpq& operator*=(const Gmpfr &f){return (*this)*= Gmpq(f);} + Gmpq& operator/=(const Gmpfr &f){return (*this)/= Gmpq(f);} + bool operator==(const Gmpfr &f) const {return mpfr_cmp_q(f.fr(),mpq())==0;} + bool operator< (const Gmpfr &f) const {return mpfr_cmp_q(f.fr(),mpq())>0;} + bool operator> (const Gmpfr &f) const {return mpfr_cmp_q(f.fr(),mpq())<0;} // Interoperability with Gmpz - Gmpq& operator+=(const Gmpz &z){return (*this)+= Gmpq(z);} - Gmpq& operator-=(const Gmpz &z){return (*this)-= Gmpq(z);} - Gmpq& operator*=(const Gmpz &z){return (*this)*= Gmpq(z);} - Gmpq& operator/=(const Gmpz &z){return (*this)/= Gmpq(z);} + Gmpq& operator+=(const Gmpz&); + Gmpq& operator-=(const Gmpz&); + Gmpq& operator*=(const Gmpz&); + Gmpq& operator/=(const Gmpz&); bool operator==(const Gmpz &z) const {return (*this)== Gmpq(z);} bool operator< (const Gmpz &z) const {return (*this)< Gmpq(z);} bool operator> (const Gmpz &z) const {return (*this)> Gmpq(z);} @@ -267,12 +298,81 @@ Gmpq::operator/=(const Gmpq &z) return *this; } +inline +Gmpq& Gmpq::operator+=(const Gmpz &z){ + if(unique()){ + mpz_addmul(mpq_numref(mpq()),mpq_denref(mpq()),z.mpz()); + mpq_canonicalize(mpq()); + }else{ + Gmpq result; + mpz_mul(mpq_numref(result.mpq()), + mpq_denref(mpq()), + z.mpz()); + mpz_add(mpq_numref(result.mpq()), + mpq_numref(mpq()), + mpq_numref(result.mpq())); + mpz_set(mpq_denref(result.mpq()),mpq_denref(mpq())); + mpq_canonicalize(result.mpq()); + swap(result); + } + return *this; +} + +inline +Gmpq& Gmpq::operator-=(const Gmpz &z){ + if(unique()){ + mpz_submul(mpq_numref(mpq()),mpq_denref(mpq()),z.mpz()); + mpq_canonicalize(mpq()); + }else{ + Gmpq result; + mpz_mul(mpq_numref(result.mpq()), + mpq_denref(mpq()), + z.mpz()); + mpz_sub(mpq_numref(result.mpq()), + mpq_numref(mpq()), + mpq_numref(result.mpq())); + mpz_set(mpq_denref(result.mpq()),mpq_denref(mpq())); + mpq_canonicalize(result.mpq()); + swap(result); + } + return *this; +} + +inline +Gmpq& Gmpq::operator*=(const Gmpz &z){ + if(unique()){ + mpz_mul(mpq_numref(mpq()),mpq_numref(mpq()),z.mpz()); + mpq_canonicalize(mpq()); + }else{ + Gmpq result; + mpz_mul(mpq_numref(result.mpq()),mpq_numref(mpq()),z.mpz()); + mpz_set(mpq_denref(result.mpq()),mpq_denref(mpq())); + mpq_canonicalize(result.mpq()); + swap(result); + } + return *this; +} + +inline +Gmpq& Gmpq::operator/=(const Gmpz &z){ + if(unique()){ + mpz_mul(mpq_denref(mpq()),mpq_denref(mpq()),z.mpz()); + mpq_canonicalize(mpq()); + }else{ + Gmpq result; + mpz_mul(mpq_denref(result.mpq()),mpq_denref(mpq()),z.mpz()); + mpz_set(mpq_numref(result.mpq()),mpq_numref(mpq())); + mpq_canonicalize(result.mpq()); + swap(result); + } + return *this; +} + inline double Gmpq::to_double() const { return mpq_get_d(mpq()); } - inline Sign Gmpq::sign() const @@ -426,14 +526,12 @@ operator>>(std::istream& is, Gmpq &z) } inline Gmpq min BOOST_PREVENT_MACRO_SUBSTITUTION(const Gmpq& x,const Gmpq& y){ - return (x<=y)?x:y; + return (x<=y)?x:y; } inline Gmpq max BOOST_PREVENT_MACRO_SUBSTITUTION(const Gmpq& x,const Gmpq& y){ - return (x>=y)?x:y; + return (x>=y)?x:y; } - CGAL_END_NAMESPACE - #endif // CGAL_GMPQ_TYPE_H diff --git a/Number_types/include/CGAL/Gmp_coercion_traits.h b/Number_types/include/CGAL/Gmp_coercion_traits.h index ad7c5aef01e..e93cf5a00ff 100644 --- a/Number_types/include/CGAL/Gmp_coercion_traits.h +++ b/Number_types/include/CGAL/Gmp_coercion_traits.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,7 @@ CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(Gmpq) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(Gmpz,Gmpzf) //CGAL_DEFINE_COERCION_TRAITS_FROM_TO(Gmpzf,Gmpzq); // todo CGAL_DEFINE_COERCION_TRAITS_FROM_TO(Gmpz,Gmpq) +CGAL_DEFINE_COERCION_TRAITS_FROM_TO(Gmpfr,Gmpq) // The following definitions reflect the interaction of the Gmp number types // with the built in types, diff --git a/Number_types/include/CGAL/mpfi_coercion_traits.h b/Number_types/include/CGAL/mpfi_coercion_traits.h index 6dd88139ba3..bd811e6045d 100644 --- a/Number_types/include/CGAL/mpfi_coercion_traits.h +++ b/Number_types/include/CGAL/mpfi_coercion_traits.h @@ -1,25 +1,25 @@ -// Copyright (c) 2007-2009 Inria Lorraine (France). All rights reserved. -// +// Copyright (c) 2007-2010 Inria Lorraine (France). All rights reserved. +// // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; version 2.1 of the License. // See the file LICENSE.LGPL distributed with CGAL. -// +// // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. -// +// // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// +// // $URL$ // $Id$ -// +// // Author: Luis Peņaranda #ifndef CGAL_MPFI_COERCION_TRAITS_H #define CGAL_MPFI_COERCION_TRAITS_H -//#ifdef CGAL_USE_MPFI +#ifdef CGAL_USE_MPFI #include #include @@ -46,7 +46,7 @@ CGAL_DEFINE_COERCION_TRAITS_FROM_TO(Gmpfr ,Gmpfi) } -//#endif // CGAL_USE_MPFI +#endif // CGAL_USE_MPFI #endif // CGAL_MPFI_COERCION_TRAITS_H // vim: tabstop=8: softtabstop=8: smarttab: shiftwidth=8: expandtab diff --git a/Number_types/include/CGAL/mpfr_coercion_traits.h b/Number_types/include/CGAL/mpfr_coercion_traits.h index 35183e58fe9..281f8b31084 100644 --- a/Number_types/include/CGAL/mpfr_coercion_traits.h +++ b/Number_types/include/CGAL/mpfr_coercion_traits.h @@ -1,19 +1,19 @@ -// Copyright (c) 2007-2009 Inria Lorraine (France). All rights reserved. -// +// Copyright (c) 2007-2010 Inria Lorraine (France). All rights reserved. +// // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; version 2.1 of the License. // See the file LICENSE.LGPL distributed with CGAL. -// +// // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. -// +// // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// +// // $URL$ // $Id$ -// +// // Author: Luis Peņaranda #ifndef CGAL_MPFR_COERCION_TRAITS_H @@ -40,7 +40,6 @@ CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long double ,Gmpfr) // coercion with gmp types CGAL_DEFINE_COERCION_TRAITS_FROM_TO(Gmpz ,Gmpfr) -CGAL_DEFINE_COERCION_TRAITS_FROM_TO(Gmpq ,Gmpfr) }