BWAPI
|
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