BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Quotient.h
Go to the documentation of this file.
00001 // Copyright (c) 1999-2007  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Number_types/include/CGAL/Quotient.h $
00019 // $Id: Quotient.h 49255 2009-05-09 15:11:47Z spion $
00020 //
00021 //
00022 // Author(s)     : Stefan Schirra, Sylvain Pion, Michael Hemmer
00023 
00024 // The template class Quotient<NT> is based on the LEDA class
00025 // leda_rational written by Stefan Naeher and Christian Uhrig.
00026 // It is basically a templated version with restricted functionality
00027 // of the version of rational in LEDA release 3.3.
00028 // The modification was done by Stefan.Schirra@mpi-sb.mpg.de
00029 
00030 // The include is done before the protect macro on purpose, because
00031 // of a cyclic dependency.
00032 
00033 #include <CGAL/number_type_basic.h>
00034 
00035 #ifndef CGAL_QUOTIENT_H
00036 #define CGAL_QUOTIENT_H
00037 
00038 #include <utility>
00039 #include <locale>
00040 
00041 #include <CGAL/Interval_nt.h>
00042 #include <CGAL/Kernel/mpl.h>
00043 
00044 #include <boost/operators.hpp>
00045 
00046 CGAL_BEGIN_NAMESPACE
00047 
00048 #define CGAL_int(T)    typename First_if_different<int,    T>::Type
00049 #define CGAL_double(T) typename First_if_different<double, T>::Type
00050 
00051 // Simplify the quotient numerator/denominator.
00052 // Currently the default template doesn't do anything.
00053 // This function is not documented as a number type requirement for now.
00054 template < typename NT >
00055 inline void
00056 simplify_quotient(NT &, NT &) {}
00057 
00058 // This one should be replaced by some functor or tag.
00059 // Meanwhile, the class is specialized for Gmpz, mpz_class, leda_integer.
00060 template < typename NT >
00061 struct Split_double
00062 {
00063   void operator()(double d, NT &num, NT &den) const
00064   {
00065     num = NT(d);
00066     den = 1;
00067   }
00068 };
00069 
00070 
00071 template <class NT_>
00072 class Quotient
00073   : boost::ordered_field_operators1< Quotient<NT_>
00074   , boost::ordered_field_operators2< Quotient<NT_>, NT_
00075   , boost::ordered_field_operators2< Quotient<NT_>, CGAL_int(NT_)
00076   , boost::ordered_field_operators2< Quotient<NT_>, CGAL_double(NT_)
00077     > > > >
00078 {
00079  public:
00080   typedef NT_        NT;
00081 
00082   Quotient()
00083     : num(0), den(1) {}
00084 
00085   Quotient(const NT& n)
00086     : num(n), den(1) {}
00087 
00088   Quotient(const CGAL_double(NT) & n)
00089   { Split_double<NT>()(n, num, den); }
00090 
00091   Quotient(const CGAL_int(NT) & n)
00092     : num(n), den(1) {}
00093 
00094   template <class T>
00095   explicit Quotient(const T& n) : num(n), den(1) {}
00096 
00097   template <class T>
00098   Quotient(const Quotient<T>& n) : num(n.numerator()), den(n.denominator()) {}
00099 
00100   Quotient& operator=(const NT & n)
00101   {
00102     num = n;
00103     den = 1;
00104     return *this;
00105   }
00106 
00107   Quotient& operator=(const CGAL_double(NT) & n)
00108   {
00109     num = n;
00110     den = 1;
00111     return *this;
00112   }
00113 
00114   Quotient& operator=(const CGAL_int(NT) & n)
00115   {
00116     num = n;
00117     den = 1;
00118     return *this;
00119   }
00120 
00121 #ifdef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
00122 
00123   template <class T1, class T2>
00124   Quotient(const T1& n, const T2& d) : num(n), den(d)
00125   { CGAL_precondition( d != 0 ); }
00126 
00127 #else
00128   template <class T1, class T2>
00129   Quotient(T1 && n, T2 && d)
00130      : num(std::forward<T1>(n)), den(std::forward<T2>(d))
00131   { CGAL_postcondition( den != 0 ); }
00132 
00133   Quotient(Quotient && q)
00134     : num(std::move(q.num)), den(std::move(q.den)) {}
00135 
00136   Quotient(NT && n)
00137     : num(std::move(n)), den(1) {}
00138 
00139   Quotient& operator=(NT && n)
00140   {
00141     num = std::move(n);
00142     den = 1;
00143     return *this;
00144   }
00145 
00146   Quotient& operator=(Quotient && q)
00147   {
00148     num = std::move(q.num);
00149     den = std::move(q.den);
00150     return *this;
00151   }
00152 #endif
00153 
00154   Quotient<NT>& operator+= (const Quotient<NT>& r);
00155   Quotient<NT>& operator-= (const Quotient<NT>& r);
00156   Quotient<NT>& operator*= (const Quotient<NT>& r);
00157   Quotient<NT>& operator/= (const Quotient<NT>& r);
00158   Quotient<NT>& operator+= (const NT& r);
00159   Quotient<NT>& operator-= (const NT& r);
00160   Quotient<NT>& operator*= (const NT& r);
00161   Quotient<NT>& operator/= (const NT& r);
00162   Quotient<NT>& operator+= (const CGAL_int(NT)& r);
00163   Quotient<NT>& operator-= (const CGAL_int(NT)& r);
00164   Quotient<NT>& operator*= (const CGAL_int(NT)& r);
00165   Quotient<NT>& operator/= (const CGAL_int(NT)& r);
00166   Quotient<NT>& operator+= (const CGAL_double(NT)& r);
00167   Quotient<NT>& operator-= (const CGAL_double(NT)& r);
00168   Quotient<NT>& operator*= (const CGAL_double(NT)& r);
00169   Quotient<NT>& operator/= (const CGAL_double(NT)& r);
00170 
00171   Quotient<NT>&    normalize();
00172 
00173   const NT&   numerator()   const { return num; }
00174   const NT&   denominator() const { return den; }
00175 
00176   void swap(Quotient &q)
00177   {
00178     using std::swap;
00179     swap(num, q.num);
00180     swap(den, q.den);
00181   }
00182 
00183 #ifdef CGAL_ROOT_OF_2_ENABLE_HISTOGRAM_OF_NUMBER_OF_DIGIT_ON_THE_COMPLEX_CONSTRUCTOR
00184   int tam() const { return std::max(num.tam(), den.tam()); }
00185 #endif
00186 
00187  public:
00188   NT   num;
00189   NT   den;
00190 };
00191 
00192 template <class NT>
00193 inline
00194 void swap(Quotient<NT> &p, Quotient<NT> &q)
00195 {
00196   p.swap(q);
00197 }
00198 
00199 template <class NT>
00200 CGAL_MEDIUM_INLINE
00201 Quotient<NT>&
00202 Quotient<NT>::normalize()
00203 {
00204   if (num == den)
00205   {
00206       num = den = 1;
00207       return *this;
00208   }
00209   if (-num == den)
00210   {
00211       num = -1;
00212       den = 1;
00213       return *this;
00214   }
00215   NT ggt = CGAL_NTS gcd(num, den);
00216   if (ggt != 1 )
00217   {
00218       num = CGAL::integral_division(num, ggt);
00219       den = CGAL::integral_division(den, ggt);
00220   }
00221   return *this;
00222 }
00223 
00224 template <class NT>
00225 CGAL_MEDIUM_INLINE
00226 Quotient<NT>&
00227 Quotient<NT>::operator+= (const Quotient<NT>& r)
00228 {
00229     num = num * r.den + r.num * den;
00230     den *= r.den;
00231     simplify_quotient(num, den);
00232     return *this;
00233 }
00234 
00235 template <class NT>
00236 CGAL_MEDIUM_INLINE
00237 Quotient<NT>&
00238 Quotient<NT>::operator-= (const Quotient<NT>& r)
00239 {
00240     num = num * r.den - r.num * den;
00241     den *= r.den;
00242     simplify_quotient(num, den);
00243     return *this;
00244 }
00245 
00246 template <class NT>
00247 CGAL_MEDIUM_INLINE
00248 Quotient<NT>&
00249 Quotient<NT>::operator*= (const Quotient<NT>& r)
00250 {
00251     num *= r.num;
00252     den *= r.den;
00253     simplify_quotient(num, den);
00254     return *this;
00255 }
00256 
00257 template <class NT>
00258 CGAL_MEDIUM_INLINE
00259 Quotient<NT>&
00260 Quotient<NT>::operator/= (const Quotient<NT>& r)
00261 {
00262     CGAL_precondition( r.num != 0 );
00263     num *= r.den;
00264     den *= r.num;
00265     simplify_quotient(num, den);
00266     return *this;
00267 }
00268 
00269 template <class NT>
00270 CGAL_MEDIUM_INLINE
00271 Quotient<NT>&
00272 Quotient<NT>::operator+= (const NT& r)
00273 {
00274     num += r * den;
00275     return *this;
00276 }
00277 
00278 template <class NT>
00279 CGAL_MEDIUM_INLINE
00280 Quotient<NT>&
00281 Quotient<NT>::operator-= (const NT& r)
00282 {
00283     num -= r * den;
00284     return *this;
00285 }
00286 
00287 template <class NT>
00288 CGAL_MEDIUM_INLINE
00289 Quotient<NT>&
00290 Quotient<NT>::operator*= (const NT& r)
00291 {
00292     num *= r;
00293     return *this;
00294 }
00295 
00296 template <class NT>
00297 CGAL_MEDIUM_INLINE
00298 Quotient<NT>&
00299 Quotient<NT>::operator/= (const NT& r)
00300 {
00301     CGAL_precondition( r != 0 );
00302     den *= r;
00303     return *this;
00304 }
00305 
00306 template <class NT>
00307 CGAL_MEDIUM_INLINE
00308 Quotient<NT>&
00309 Quotient<NT>::operator+= (const CGAL_int(NT)& r)
00310 {
00311     num += r * den;
00312     return *this;
00313 }
00314 
00315 template <class NT>
00316 CGAL_MEDIUM_INLINE
00317 Quotient<NT>&
00318 Quotient<NT>::operator-= (const CGAL_int(NT)& r)
00319 {
00320     num -= r * den;
00321     return *this;
00322 }
00323 
00324 template <class NT>
00325 CGAL_MEDIUM_INLINE
00326 Quotient<NT>&
00327 Quotient<NT>::operator*= (const CGAL_int(NT)& r)
00328 {
00329     num *= r;
00330     return *this;
00331 }
00332 
00333 template <class NT>
00334 CGAL_MEDIUM_INLINE
00335 Quotient<NT>&
00336 Quotient<NT>::operator/= (const CGAL_int(NT)& r)
00337 {
00338     CGAL_precondition( r != 0 );
00339     den *= r;
00340     return *this;
00341 }
00342 
00343 template <class NT>
00344 CGAL_MEDIUM_INLINE
00345 Quotient<NT>&
00346 Quotient<NT>::operator+= (const CGAL_double(NT)& r)
00347 {
00348   //num += r * den; 
00349   NT r_num, r_den; 
00350   Split_double<NT>()(r,r_num,r_den);
00351   num = num*r_den + r_num*den;
00352   den *=r_den; 
00353   return *this;
00354 }
00355 
00356 template <class NT>
00357 CGAL_MEDIUM_INLINE
00358 Quotient<NT>&
00359 Quotient<NT>::operator-= (const CGAL_double(NT)& r)
00360 {
00361   //num -= r * den;
00362   NT r_num, r_den; 
00363   Split_double<NT>()(r,r_num,r_den);
00364   num =  num*r_den - r_num*den;
00365   den *= r_den; 
00366   return *this;
00367 }
00368 
00369 template <class NT>
00370 CGAL_MEDIUM_INLINE
00371 Quotient<NT>&
00372 Quotient<NT>::operator*= (const CGAL_double(NT)& r)
00373 {
00374   // num *= r;
00375   
00376   NT r_num, r_den; 
00377   Split_double<NT>()(r,r_num,r_den);
00378   num *= r_num;
00379   den *= r_den; 
00380   return *this;
00381 }
00382 
00383 template <class NT>
00384 CGAL_MEDIUM_INLINE
00385 Quotient<NT>&
00386 Quotient<NT>::operator/= (const CGAL_double(NT)& r)
00387 {
00388   CGAL_precondition( r != 0 );
00389   NT r_num, r_den; 
00390   Split_double<NT>()(r,r_num,r_den);
00391   num *= r_den;
00392   den *= r_num; 
00393   return *this;
00394 }
00395 
00396 template <class NT>
00397 CGAL_MEDIUM_INLINE
00398 Comparison_result
00399 quotient_cmp(const Quotient<NT>& x, const Quotient<NT>& y)
00400 {
00401     // No assumptions on the sign of  den  are made
00402 
00403     // code assumes that SMALLER == - 1;
00404     CGAL_precondition( SMALLER == static_cast<Comparison_result>(-1) );
00405 
00406     int xsign = CGAL_NTS sign(x.num) * CGAL_NTS sign(x.den) ;
00407     int ysign = CGAL_NTS sign(y.num) * CGAL_NTS sign(y.den) ;
00408     if (xsign == 0) return static_cast<Comparison_result>(-ysign);
00409     if (ysign == 0) return static_cast<Comparison_result>(xsign);
00410     // now (x != 0) && (y != 0)
00411     int diff = xsign - ysign;
00412     if (diff == 0)
00413     {
00414         int msign = CGAL_NTS sign(x.den) * CGAL_NTS sign(y.den);
00415         NT leftop  = x.num * y.den * msign;
00416         NT rightop = y.num * x.den * msign;
00417         return CGAL_NTS compare(leftop, rightop);
00418     }
00419     else
00420     {
00421         return (xsign < ysign) ? SMALLER : LARGER;
00422     }
00423 }
00424 
00425 
00426 template <class NT>
00427 std::ostream&
00428 operator<<(std::ostream& s, const Quotient<NT>& r)
00429 {
00430    return s << r.numerator() << "/" << r.denominator();
00431 }
00432 
00433 template <class NT>
00434 std::istream&
00435 operator>>(std::istream& in, Quotient<NT>& r)
00436 {
00437   /* format  num/den  or simply  num  */
00438 
00439   char c = 0;
00440 
00441   while (in.get(c) && std::isspace(c, std::locale::classic() )) {}
00442   if ( !in ) return in;
00443   in.putback(c);
00444 
00445   NT num;
00446   NT den(1);
00447   in >> num;
00448 
00449   while (in.get(c) && std::isspace(c, std::locale::classic() )) {}
00450   if (( in ) && ( c == '/'))
00451   {
00452       while (in.get(c) && std::isspace(c, std::locale::classic() )) {}
00453       CGAL_assertion( in != 0 );
00454       in.putback(c);
00455       in >> den;
00456   }
00457   else
00458   {
00459       in.putback(c);
00460       if ( in.eof() ) in.clear();
00461   }
00462   r = Quotient<NT>( num, den);
00463   return in;
00464 }
00465 
00466 template< class NT >
00467 inline
00468 Quotient<NT>
00469 operator+( const Quotient<NT>& x ) {
00470   return Quotient<NT>(x);
00471 }
00472 
00473 template <class NT>
00474 inline
00475 Quotient<NT>
00476 operator-(const Quotient<NT>& x)
00477 { return Quotient<NT>(-x.num,x.den); }
00478 
00479 
00480 template <class NT>
00481 CGAL_MEDIUM_INLINE
00482 NT
00483 quotient_truncation(const Quotient<NT>& r)
00484 { return (r.num / r.den); }
00485 
00486 
00487 
00488 template <class NT>
00489 CGAL_MEDIUM_INLINE
00490 bool
00491 operator==(const Quotient<NT>& x, const Quotient<NT>& y)
00492 { return x.num * y.den == x.den * y.num; }
00493 
00494 template <class NT>
00495 CGAL_MEDIUM_INLINE
00496 bool
00497 operator==(const Quotient<NT>& x, const NT& y)
00498 { return x.den * y == x.num; }
00499 
00500 template <class NT>
00501 inline
00502 bool
00503 operator==(const Quotient<NT>& x, const CGAL_int(NT) & y)
00504 { return x.den * y == x.num; }
00505 
00506 template <class NT>
00507 inline
00508 bool
00509 operator==(const Quotient<NT>& x, const CGAL_double(NT) & y)
00510 { return x.den * y == x.num; }
00511 
00512 
00513 
00514 template <class NT>
00515 CGAL_MEDIUM_INLINE
00516 bool
00517 operator<(const Quotient<NT>& x, const Quotient<NT>& y)
00518 {
00519   return quotient_cmp(x,y) == SMALLER;
00520 }
00521 
00522 template <class NT>
00523 CGAL_MEDIUM_INLINE
00524 bool
00525 operator<(const Quotient<NT>& x, const NT& y)
00526 {
00527   return quotient_cmp(x,Quotient<NT>(y)) == SMALLER;
00528 }
00529 
00530 template <class NT>
00531 CGAL_MEDIUM_INLINE
00532 bool
00533 operator<(const Quotient<NT>& x, const CGAL_int(NT)& y)
00534 {
00535   return quotient_cmp(x,Quotient<NT>(y)) == SMALLER;
00536 }
00537 
00538 template <class NT>
00539 CGAL_MEDIUM_INLINE
00540 bool
00541 operator<(const Quotient<NT>& x, const CGAL_double(NT)& y)
00542 {
00543   return quotient_cmp(x,Quotient<NT>(y)) == SMALLER;
00544 }
00545 
00546 
00547 template <class NT>
00548 inline
00549 bool
00550 operator>(const Quotient<NT>& x, const NT& y)
00551 { return quotient_cmp(x,Quotient<NT>(y)) == LARGER; }
00552 
00553 template <class NT>
00554 inline
00555 bool
00556 operator>(const Quotient<NT>& x, const CGAL_int(NT)& y)
00557 { return quotient_cmp(x, Quotient<NT>(y)) == LARGER; }
00558 
00559 template <class NT>
00560 inline
00561 bool
00562 operator>(const Quotient<NT>& x, const CGAL_double(NT)& y)
00563 { return quotient_cmp(x, Quotient<NT>(y)) == LARGER; }
00564 
00565 
00566 template< class NT >
00567 class Is_valid< Quotient<NT> >
00568   : public std::unary_function< Quotient<NT>, bool > {
00569   public :
00570     bool operator()( const Quotient<NT>& x ) const {
00571       return is_valid(x.num) && is_valid(x.den);
00572     }
00573 };
00574 
00575 
00576 template <class NT>
00577 inline
00578 const NT&
00579 denominator(const Quotient<NT>& q)
00580 { return q.den ; }
00581 
00582 template <class NT>
00583 inline
00584 const NT&
00585 numerator(const Quotient<NT>& q)
00586 { return q.num ; }
00587 
00588 // The min/max are functions are needed since LEDA defines template
00589 // min/max functions which clash with std::min/max with ADL.
00590 template <class NT>
00591 inline
00592 const Quotient<NT>&
00593 min
00594 BOOST_PREVENT_MACRO_SUBSTITUTION
00595 (const Quotient<NT>& p, const Quotient<NT>& q)
00596 {
00597   return (std::min)(p, q);
00598 }
00599 template <class NT>
00600 inline
00601 const Quotient<NT>&
00602 max
00603 BOOST_PREVENT_MACRO_SUBSTITUTION
00604 (const Quotient<NT>& p, const Quotient<NT>& q)
00605 {
00606   return (std::max)(p, q);
00607 }
00608 
00609 /*
00610 template <class NT>
00611 NT
00612 gcd(const NT&, const NT&)
00613 { return NT(1); }
00614 */
00615 
00616 #undef CGAL_double
00617 #undef CGAL_int
00618 
00619 //
00620 // Algebraic structure traits
00621 //
00622 namespace INTERN_QUOTIENT {
00623   template< class NT, class Sqrt_functor >
00624   class Sqrt_selector {
00625     public:
00626       class Sqrt
00627         : public std::unary_function< NT, NT > {
00628         public:
00629           NT operator()( const NT& x ) const {
00630             CGAL_precondition(x > 0);
00631             return NT(CGAL_NTS sqrt(x.numerator()*x.denominator()),
00632                       x.denominator());
00633           }
00634       };
00635   };
00636 
00637   template< class NT >
00638   class Sqrt_selector< NT, Null_functor > {
00639     public:
00640       typedef Null_functor Sqrt;
00641   };
00642 
00643 // TODO: Algebraic_category could be Field_with_sqrt_tag, if NT
00644 //       is INEXACT (because Sqrt can be inexact) and has a Sqrt-functor.
00645 template<class NT> class Algebraic_structure_traits_quotient_base;
00646 
00647 template< class NT > class Algebraic_structure_traits_quotient_base< Quotient<NT> >
00648   : public Algebraic_structure_traits_base< Quotient<NT>, Field_tag >  {
00649 
00650 public:
00651     typedef Quotient<NT> Type;
00652 
00653     typedef typename Algebraic_structure_traits<NT>::Is_exact        Is_exact;
00654     typedef Tag_false Is_numerical_sensitive;
00655 
00656 
00657 
00658     class Is_square
00659         : public std::binary_function< Quotient<NT>, Quotient<NT>&, bool > {
00660     public:
00661         bool operator()( Quotient<NT> x, Quotient<NT>& y ) const {
00662             NT x_num, x_den, y_num, y_den;
00663             x.normalize();
00664             x_num = x.numerator();
00665             x_den = x.denominator();
00666 
00667             typename Algebraic_structure_traits<NT>::Is_square is_square;
00668             bool num_is_square = is_square(x_num,y_num);
00669             bool den_is_square = is_square(x_den,y_den);
00670             y= Quotient<NT>(y_num,y_den);
00671             return num_is_square && den_is_square;
00672         }
00673         bool operator()(Quotient<NT> x) const {
00674             x.normalize();
00675             typename Algebraic_structure_traits<NT>::Is_square is_square;
00676             return is_square(x.numerator())&&is_square(x.denominator());
00677         }
00678 
00679     };
00680 
00681     typedef typename boost::mpl::if_c<
00682         !boost::is_same< typename Algebraic_structure_traits<NT>::Sqrt,
00683                          Null_functor >::value,
00684          typename INTERN_QUOTIENT::Sqrt_selector< Type,
00685                                                   Is_exact >::Sqrt,
00686          Null_functor
00687                             >::type Sqrt;
00688 
00689     class Simplify
00690       : public std::unary_function< Type&, void > {
00691       public:
00692         void operator()( Type& x) const {
00693             x.normalize();
00694         }
00695     };
00696 };
00697 
00698 
00699 template<class NT> class Real_embeddable_traits_quotient_base;
00700 // Real embeddable traits
00701 template < class NT > class Real_embeddable_traits_quotient_base< Quotient<NT> >
00702   : public INTERN_RET::Real_embeddable_traits_base< Quotient<NT>,
00703                   typename Real_embeddable_traits< NT >::Is_real_embeddable > {
00704   public:
00705     typedef Quotient<NT> Type;
00706 
00707     class Compare
00708       : public std::binary_function< Type, Type,
00709                                 Comparison_result > {
00710       public:
00711         Comparison_result operator()( const Type& x,
00712                                             const Type& y ) const {
00713           return quotient_cmp(x, y);
00714         }
00715     };
00716 
00717     class To_double
00718       : public std::unary_function< Type, double > {
00719       public:
00720         double operator()( const Type& x ) const {
00721         // Original global function was marked with an TODO!!
00722           if (x.num == 0 )
00723             return 0;
00724 
00725           double nd = CGAL_NTS to_double( x.num );
00726 
00727           if (x.den == 1 )
00728             return nd;
00729 
00730           double dd = CGAL_NTS to_double( x.den );
00731 
00732           if ( CGAL_NTS is_finite( x.den ) && CGAL_NTS is_finite( x.num ) )
00733             return nd/dd;
00734 
00735           if ( CGAL_NTS abs(x.num) > CGAL_NTS abs(x.den) )
00736           {
00737               NT  nt_div = x.num / x.den;
00738               double divd = CGAL_NTS to_double(nt_div);
00739               if ( divd >= std::ldexp(1.0,53) )
00740               { return divd; }
00741           }
00742           if ( CGAL_NTS abs(x.num) < CGAL_NTS abs(x.den) )
00743           { return 1.0 / CGAL_NTS to_double( NT(1) / x ); }
00744 
00745           return nd/dd;
00746         }
00747     };
00748 
00749     class To_interval
00750       : public std::unary_function< Type, std::pair< double, double > > {
00751       public:
00752         std::pair<double, double> operator()( const Type& x ) const {
00753           Interval_nt<> quot =
00754                           Interval_nt<>(CGAL_NTS to_interval(x.numerator())) /
00755                           Interval_nt<>(CGAL_NTS to_interval(x.denominator()));
00756           return std::make_pair(quot.inf(), quot.sup());
00757         }
00758     };
00759 
00760     class Is_finite
00761       : public std::unary_function< Type, bool > {
00762       public:
00763         bool operator()( const Type& x ) const {
00764           return CGAL_NTS is_finite(x.num) && CGAL_NTS is_finite(x.den);
00765         }
00766     };
00767 };
00768 } // namespace INTERN_QUOTIENT
00769 
00770 template< class NT > class Algebraic_structure_traits< Quotient<NT> >
00771     : public INTERN_QUOTIENT::Algebraic_structure_traits_quotient_base<
00772 Quotient<NT> >{};
00773 
00774 template< class NT > class Real_embeddable_traits< Quotient<NT> >
00775     : public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base<
00776 Quotient<NT> >{};
00777 
00778 
00779 // self coercion
00780 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF_TEM( Quotient<NT>, class NT)
00781 
00782 // from int to Quotient
00783 template <class NT>
00784 struct Coercion_traits<typename First_if_different<int, NT>::Type,Quotient<NT> >
00785 {
00786     typedef Tag_true  Are_explicit_interoperable;
00787     typedef Tag_true  Are_implicit_interoperable;
00788     typedef Quotient<NT> Type;
00789     struct Cast{
00790         typedef Type result_type;
00791         Type operator()(const Quotient<NT>& x)   const { return x;}
00792         Type operator()(
00793                 const typename First_if_different<int, NT>::Type& x) const {
00794             return Type(x);}
00795     };
00796 };
00797 template <class NT>
00798 struct Coercion_traits<Quotient<NT>,typename First_if_different<int, NT>::Type>
00799     :public Coercion_traits<typename First_if_different<int, NT>::Type,
00800 Quotient<NT> >{};
00801 
00802 // from double to Quotient
00803 template <class NT>
00804 struct Coercion_traits<typename First_if_different<double, NT>::Type,
00805 Quotient<NT> >{
00806     typedef Tag_true  Are_explicit_interoperable;
00807     typedef Tag_true  Are_implicit_interoperable;
00808     typedef Quotient<NT> Type;
00809     struct Cast{
00810         typedef Type result_type;
00811         Type operator()(const Quotient<NT>& x)   const { return x;}
00812         Type operator()(
00813                 const typename First_if_different<double, NT>::Type& x) const {
00814             return Type(x);}
00815     };
00816 };
00817 template <class NT>
00818 struct Coercion_traits<Quotient<NT>,
00819 typename First_if_different<double, NT>::Type>
00820     :public Coercion_traits<typename First_if_different<double, NT>::Type,
00821 Quotient<NT> >
00822 {};
00823 
00824 // from NT to Quotient
00825 CGAL_DEFINE_COERCION_TRAITS_FROM_TO_TEM ( NT, Quotient<NT>, class NT)
00826 
00827 
00830 template <class NT>
00831 class Fraction_traits< Quotient<NT> > {
00832 public:
00833     typedef Quotient<NT> Type;
00834     typedef ::CGAL::Tag_true Is_fraction;
00835     typedef NT Numerator_type;
00836     typedef Numerator_type Denominator_type;
00837 
00838     //TODO: check whether Numerator_type has a GCD.
00839     //will use Scalar_factor from Scalar_factor_traits (not implemented yet)
00840     //for more details see EXACUS:NumeriX/include/NiX/Scalar_factor_traits.h
00841     typedef typename Algebraic_structure_traits< Numerator_type >::Gcd Common_factor;
00842 
00843     class Decompose {
00844     public:
00845         typedef Type first_argument_type;
00846         typedef Numerator_type& second_argument_type;
00847         typedef Numerator_type& third_argument_type;
00848         void operator () (
00849                 const Type& rat,
00850                 Numerator_type& num,
00851                 Numerator_type& den) {
00852             num = rat.numerator();
00853             den = rat.denominator();
00854         }
00855     };
00856 
00857     class Compose {
00858     public:
00859         typedef Numerator_type first_argument_type;
00860         typedef Numerator_type second_argument_type;
00861         typedef Type result_type;
00862         Type operator ()(
00863                 const Numerator_type& num ,
00864                 const Numerator_type& den ) {
00865             Type result(num, den);
00866             return result;
00867         }
00868     };
00869 };
00870 
00871 CGAL_END_NAMESPACE
00872 
00873 #endif  // CGAL_QUOTIENT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines