BWAPI
|
00001 // Copyright (c) 2001-2007 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation; version 2.1 of the License. 00007 // See the file LICENSE.LGPL distributed with CGAL. 00008 // 00009 // Licensees holding a valid commercial license may use this file in 00010 // accordance with the commercial license agreement provided with the software. 00011 // 00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00014 // 00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Number_types/include/CGAL/MP_Float.h $ 00016 // $Id: MP_Float.h 49008 2009-04-29 13:57:45Z hemmer $ 00017 // 00018 // 00019 // Author(s) : Sylvain Pion 00020 00021 #ifndef CGAL_MP_FLOAT_H 00022 #define CGAL_MP_FLOAT_H 00023 00024 #include <CGAL/number_type_basic.h> 00025 #include <CGAL/Algebraic_structure_traits.h> 00026 #include <CGAL/Real_embeddable_traits.h> 00027 #include <CGAL/Coercion_traits.h> 00028 #include <CGAL/Quotient.h> 00029 #include <CGAL/Root_of_2.h> 00030 00031 #include <CGAL/utils.h> 00032 00033 #include <CGAL/Interval_nt.h> 00034 #include <iostream> 00035 #include <vector> 00036 #include <algorithm> 00037 00038 // MP_Float : multiprecision scaled integers. 00039 00040 // Some invariants on the internal representation : 00041 // - zero is represented by an empty vector, and whatever exp. 00042 // - no leading or trailing zero in the vector => unique 00043 00044 // The main algorithms are : 00045 // - Addition/Subtraction 00046 // - Multiplication 00047 // - Integral division div(), gcd(), operator%(). 00048 // - Comparison 00049 // - to_double() / to_interval() 00050 // - Construction from a double. 00051 // - IOs 00052 00053 // TODO : 00054 // - The exponent really overflows sometimes -> make it multiprecision. 00055 // - Write a generic wrapper that adds an exponent to be used by MP integers. 00056 // - Karatsuba (or other) ? Would be fun to implement at least. 00057 // - Division, sqrt... : different options : 00058 // - nothing 00059 // - convert to double, take approximation, compute over double, reconstruct 00060 00061 CGAL_BEGIN_NAMESPACE 00062 00063 class MP_Float; 00064 00065 template < typename > class Quotient; // Needed for overloaded To_double 00066 00067 namespace INTERN_MP_FLOAT { 00068 Comparison_result compare(const MP_Float&, const MP_Float&); 00069 MP_Float square(const MP_Float&); 00070 00071 // to_double() returns, not the closest double, but a one bit error is allowed. 00072 // We guarantee : to_double(MP_Float(double d)) == d. 00073 double to_double(const MP_Float&); 00074 double to_double(const Root_of_2<MP_Float> &x); 00075 double to_double(const Quotient<MP_Float>&); 00076 std::pair<double,double> to_interval(const MP_Float &); 00077 // std::pair<double,double> to_interval(const Root_of_2<MP_Float>&); // TODO ? 00078 std::pair<double,double> to_interval(const Quotient<MP_Float>&); 00079 MP_Float div(const MP_Float& n1, const MP_Float& n2); 00080 MP_Float gcd(const MP_Float& a, const MP_Float& b); 00081 } 00082 00083 std::pair<double, int> 00084 to_double_exp(const MP_Float &b); 00085 00086 // Returns (first * 2^second), an interval surrounding b. 00087 std::pair<std::pair<double, double>, int> 00088 to_interval_exp(const MP_Float &b); 00089 00090 std::ostream & 00091 operator<< (std::ostream & os, const MP_Float &b); 00092 00093 // This one is for debug. 00094 std::ostream & 00095 print (std::ostream & os, const MP_Float &b); 00096 00097 std::istream & 00098 operator>> (std::istream & is, MP_Float &b); 00099 00100 MP_Float operator+(const MP_Float &a, const MP_Float &b); 00101 MP_Float operator-(const MP_Float &a, const MP_Float &b); 00102 MP_Float operator*(const MP_Float &a, const MP_Float &b); 00103 MP_Float operator%(const MP_Float &a, const MP_Float &b); 00104 00105 class MP_Float 00106 { 00107 public: 00108 typedef short limb; 00109 typedef int limb2; 00110 typedef double exponent_type; 00111 00112 typedef std::vector<limb> V; 00113 typedef V::const_iterator const_iterator; 00114 typedef V::iterator iterator; 00115 00116 private: 00117 00118 void remove_leading_zeros() 00119 { 00120 while (!v.empty() && v.back() == 0) 00121 v.pop_back(); 00122 } 00123 00124 void remove_trailing_zeros() 00125 { 00126 if (v.empty() || v.front() != 0) 00127 return; 00128 00129 iterator i = v.begin(); 00130 for (++i; *i == 0; ++i) 00131 ; 00132 exp += i-v.begin(); 00133 v.erase(v.begin(), i); 00134 } 00135 00136 // This union is used to convert an unsigned short to a short with 00137 // the same binary representation, without invoking implementation-defined 00138 // behavior (standard 4.7.3). 00139 // It is needed by PGCC, which behaves differently from the others. 00140 union to_signed { 00141 unsigned short us; 00142 short s; 00143 }; 00144 00145 // The constructors from float/double/long_double are factorized in the 00146 // following template : 00147 template < typename T > 00148 void construct_from_builtin_fp_type(T d); 00149 00150 public: 00151 #ifdef CGAL_ROOT_OF_2_ENABLE_HISTOGRAM_OF_NUMBER_OF_DIGIT_ON_THE_COMPLEX_CONSTRUCTOR 00152 int tam() const { return v.size(); } 00153 #endif 00154 00155 // Splits a limb2 into 2 limbs (high and low). 00156 static 00157 void split(limb2 l, limb & high, limb & low) 00158 { 00159 to_signed l2 = {static_cast<limb>(l)}; 00160 low = l2.s; 00161 high = (l - low) >> (8*sizeof(limb)); 00162 } 00163 00164 // Given a limb2, returns the higher limb. 00165 static 00166 limb higher_limb(limb2 l) 00167 { 00168 limb high, low; 00169 split(l, high, low); 00170 return high; 00171 } 00172 00173 void canonicalize() 00174 { 00175 remove_leading_zeros(); 00176 remove_trailing_zeros(); 00177 } 00178 00179 MP_Float() 00180 : exp(0) 00181 { 00182 CGAL_assertion(sizeof(limb2) == 2*sizeof(limb)); 00183 CGAL_assertion(v.empty()); 00184 // Creates zero. 00185 } 00186 00187 #if 0 00188 // Causes ambiguities 00189 MP_Float(limb i) 00190 : v(1,i), exp(0) 00191 { 00192 remove_leading_zeros(); 00193 } 00194 #endif 00195 00196 MP_Float(limb2 i) 00197 : v(2), exp(0) 00198 { 00199 split(i, v[1], v[0]); 00200 canonicalize(); 00201 } 00202 00203 MP_Float(float d); 00204 00205 MP_Float(double d); 00206 00207 MP_Float(long double d); 00208 00209 #ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE 00210 MP_Float(MP_Float && m) 00211 : v(std::move(m.v)), exp(m.exp) {} 00212 00213 MP_Float& operator=(MP_Float && m) 00214 { 00215 clear(); 00216 swap(m); 00217 return *this; 00218 } 00219 #endif 00220 00221 MP_Float operator+() const { 00222 return *this; 00223 } 00224 00225 MP_Float operator-() const 00226 { 00227 return MP_Float() - *this; 00228 } 00229 00230 MP_Float& operator+=(const MP_Float &a) { return *this = *this + a; } 00231 MP_Float& operator-=(const MP_Float &a) { return *this = *this - a; } 00232 MP_Float& operator*=(const MP_Float &a) { return *this = *this * a; } 00233 MP_Float& operator%=(const MP_Float &a) { return *this = *this % a; } 00234 00235 exponent_type max_exp() const 00236 { 00237 return v.size() + exp; 00238 } 00239 00240 exponent_type min_exp() const 00241 { 00242 return exp; 00243 } 00244 00245 limb of_exp(exponent_type i) const 00246 { 00247 if (i < exp || i >= max_exp()) 00248 return 0; 00249 return v[static_cast<int>(i-exp)]; 00250 } 00251 00252 bool is_zero() const 00253 { 00254 return v.empty(); 00255 } 00256 00257 Sign sign() const 00258 { 00259 if (v.empty()) 00260 return ZERO; 00261 if (v.back()>0) 00262 return POSITIVE; 00263 CGAL_assertion(v.back()<0); 00264 return NEGATIVE; 00265 } 00266 00267 void clear() 00268 { 00269 v.clear(); 00270 exp = 0; 00271 } 00272 00273 void swap(MP_Float &m) 00274 { 00275 std::swap(v, m.v); 00276 std::swap(exp, m.exp); 00277 } 00278 00279 // Converts to a rational type (e.g. Gmpq). 00280 template < typename T > 00281 T to_rational() const 00282 { 00283 const unsigned log_limb = 8 * sizeof(MP_Float::limb); 00284 00285 if (is_zero()) 00286 return 0; 00287 00288 MP_Float::const_iterator i; 00289 exponent_type exp2 = min_exp() * log_limb; 00290 T res = 0; 00291 00292 for (i = v.begin(); i != v.end(); ++i) 00293 { 00294 res += std::ldexp(static_cast<double>(*i), 00295 static_cast<int>(exp2)); 00296 exp2 += log_limb; 00297 } 00298 00299 return res; 00300 } 00301 00302 std::size_t size() const 00303 { 00304 return v.size(); 00305 } 00306 00307 // Returns a scaling factor (in limbs) which would be good to extract to get 00308 // a value with an exponent close to 0. 00309 exponent_type find_scale() const 00310 { 00311 return exp + v.size(); 00312 } 00313 00314 // Rescale the value by some factor (in limbs). (substract the exponent) 00315 void rescale(exponent_type scale) 00316 { 00317 if (v.size() != 0) 00318 exp -= scale; 00319 } 00320 00321 // Accessory function that finds the least significant bit set (its position). 00322 static unsigned short 00323 lsb(limb l) 00324 { 00325 unsigned short nb = 0; 00326 for (; (l&1)==0; ++nb, l>>=1) 00327 ; 00328 return nb; 00329 } 00330 00331 // This one is needed for normalizing gcd so that the mantissa is odd 00332 // and non-negative, and the exponent is 0. 00333 void gcd_normalize() 00334 { 00335 const unsigned log_limb = 8 * sizeof(MP_Float::limb); 00336 if (is_zero()) 00337 return; 00338 // First find how many least significant bits are 0 in the last digit. 00339 unsigned short nb = lsb(v[0]); 00340 if (nb != 0) 00341 *this = *this * (1<<(log_limb-nb)); 00342 CGAL_assertion((v[0]&1) != 0); 00343 exp=0; 00344 if (sign() == NEGATIVE) 00345 *this = - *this; 00346 } 00347 00348 MP_Float unit_part() const 00349 { 00350 if (is_zero()) 00351 return 1; 00352 MP_Float r = (sign() > 0) ? *this : - *this; 00353 CGAL_assertion(r.v.begin() != r.v.end()); 00354 unsigned short nb = lsb(r.v[0]); 00355 r.v.clear(); 00356 r.v.push_back(1<<nb); 00357 return (sign() > 0) ? r : -r; 00358 } 00359 00360 bool is_integer() const 00361 { 00362 return is_zero() || (exp >= 0); 00363 } 00364 00365 V v; 00366 exponent_type exp; 00367 }; 00368 00369 namespace CGALi{ 00370 std::pair<MP_Float, MP_Float> // <quotient, remainder> 00371 division(const MP_Float & n, const MP_Float & d); 00372 } // namespace CGALi 00373 00374 inline 00375 void swap(MP_Float &m, MP_Float &n) 00376 { m.swap(n); } 00377 00378 inline 00379 bool operator<(const MP_Float &a, const MP_Float &b) 00380 { return INTERN_MP_FLOAT::compare(a, b) == SMALLER; } 00381 00382 inline 00383 bool operator>(const MP_Float &a, const MP_Float &b) 00384 { return b < a; } 00385 00386 inline 00387 bool operator>=(const MP_Float &a, const MP_Float &b) 00388 { return ! (a < b); } 00389 00390 inline 00391 bool operator<=(const MP_Float &a, const MP_Float &b) 00392 { return ! (a > b); } 00393 00394 inline 00395 bool operator==(const MP_Float &a, const MP_Float &b) 00396 { return (a.v == b.v) && (a.v.empty() || (a.exp == b.exp)); } 00397 00398 inline 00399 bool operator!=(const MP_Float &a, const MP_Float &b) 00400 { return ! (a == b); } 00401 00402 MP_Float 00403 approximate_sqrt(const MP_Float &d); 00404 00405 MP_Float 00406 approximate_division(const MP_Float &n, const MP_Float &d); 00407 00408 // Algebraic structure traits 00409 template <> class Algebraic_structure_traits< MP_Float > 00410 : public Algebraic_structure_traits_base< MP_Float, 00411 Unique_factorization_domain_tag 00412 // with some work on mod/div it could be Euclidean_ring_tag 00413 > { 00414 public: 00415 00416 typedef Tag_true Is_exact; 00417 typedef Tag_true Is_numerical_sensitive; 00418 00419 struct Unit_part 00420 : public std::unary_function< Type , Type > 00421 { 00422 Type operator()(const Type &x) const { 00423 return x.unit_part(); 00424 } 00425 }; 00426 00427 struct Integral_division 00428 : public std::binary_function< Type, 00429 Type, 00430 Type > { 00431 public: 00432 Type operator()( 00433 const Type& x, 00434 const Type& y ) const { 00435 std::pair<MP_Float, MP_Float> res = CGALi::division(x, y); 00436 CGAL_assertion_msg(res.second == 0, 00437 "exact_division() called with operands which do not divide"); 00438 return res.first; 00439 } 00440 }; 00441 00442 00443 class Square 00444 : public std::unary_function< Type, Type > { 00445 public: 00446 Type operator()( const Type& x ) const { 00447 return INTERN_MP_FLOAT::square(x); 00448 } 00449 }; 00450 00451 class Gcd 00452 : public std::binary_function< Type, Type, 00453 Type > { 00454 public: 00455 Type operator()( const Type& x, 00456 const Type& y ) const { 00457 return INTERN_MP_FLOAT::gcd( x, y ); 00458 } 00459 }; 00460 00461 class Div 00462 : public std::binary_function< Type, Type, 00463 Type > { 00464 public: 00465 Type operator()( const Type& x, 00466 const Type& y ) const { 00467 return INTERN_MP_FLOAT::div( x, y ); 00468 } 00469 }; 00470 00471 typedef INTERN_AST::Mod_per_operator< Type > Mod; 00472 // Default implementation of Divides functor for unique factorization domains 00473 // x divides y if gcd(y,x) equals x up to inverses 00474 class Divides 00475 : public std::binary_function<Type,Type,bool>{ 00476 public: 00477 bool operator()( const Type& x, const Type& y) const { 00478 return CGALi::division(y,x).second == 0 ; 00479 } 00480 // second operator computing q = x/y 00481 bool operator()( const Type& x, const Type& y, Type& q) const { 00482 std::pair<Type,Type> qr = CGALi::division(y,x); 00483 q=qr.first; 00484 return qr.second == 0; 00485 00486 } 00487 CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT( Type , bool) 00488 }; 00489 }; 00490 00491 00492 00493 // Real embeddable traits 00494 template <> class Real_embeddable_traits< MP_Float > 00495 : public INTERN_RET::Real_embeddable_traits_base< MP_Float , CGAL::Tag_true > { 00496 public: 00497 00498 class Sgn 00499 : public std::unary_function< Type, ::CGAL::Sign > { 00500 public: 00501 ::CGAL::Sign operator()( const Type& x ) const { 00502 return x.sign(); 00503 } 00504 }; 00505 00506 class Compare 00507 : public std::binary_function< Type, Type, 00508 Comparison_result > { 00509 public: 00510 Comparison_result operator()( const Type& x, 00511 const Type& y ) const { 00512 return INTERN_MP_FLOAT::compare( x, y ); 00513 } 00514 }; 00515 00516 class To_double 00517 : public std::unary_function< Type, double > { 00518 public: 00519 double operator()( const Type& x ) const { 00520 return INTERN_MP_FLOAT::to_double( x ); 00521 } 00522 }; 00523 00524 class To_interval 00525 : public std::unary_function< Type, std::pair< double, double > > { 00526 public: 00527 std::pair<double, double> operator()( const Type& x ) const { 00528 return INTERN_MP_FLOAT::to_interval( x ); 00529 } 00530 }; 00531 }; 00532 00533 00534 namespace CGALi { 00535 // This compares the absolute values of the odd-mantissa. 00536 // (take the mantissas, get rid of all powers of 2, compare 00537 // the absolute values) 00538 inline 00539 Sign 00540 compare_bitlength(const MP_Float &a, const MP_Float &b) 00541 { 00542 if (a.is_zero()) 00543 return b.is_zero() ? EQUAL : SMALLER; 00544 if (b.is_zero()) 00545 return LARGER; 00546 00547 //Real_embeddable_traits<MP_Float>::Abs abs; 00548 00549 MP_Float aa = CGAL_NTS abs(a); 00550 MP_Float bb = CGAL_NTS abs(b); 00551 00552 if (aa.size() > (bb.size() + 2)) return LARGER; 00553 if (bb.size() > (aa.size() + 2)) return SMALLER; 00554 00555 // multiply by 2 till last bit is 1. 00556 while (((aa.v[0]) & 1) == 0) // last bit is zero 00557 aa = aa + aa; 00558 00559 while (((bb.v[0]) & 1) == 0) // last bit is zero 00560 bb = bb + bb; 00561 00562 // sizes might have changed 00563 if (aa.size() > bb.size()) return LARGER; 00564 if (aa.size() < bb.size()) return SMALLER; 00565 00566 for (std::size_t i = aa.size(); i > 0; --i) 00567 { 00568 if (aa.v[i-1] > bb.v[i-1]) return LARGER; 00569 if (aa.v[i-1] < bb.v[i-1]) return SMALLER; 00570 } 00571 return EQUAL; 00572 } 00573 00574 inline // Move it to libCGAL once it's stable. 00575 std::pair<MP_Float, MP_Float> // <quotient, remainder> 00576 division(const MP_Float & n, const MP_Float & d) 00577 { 00578 typedef MP_Float::exponent_type exponent_type; 00579 00580 MP_Float remainder = n, divisor = d; 00581 00582 CGAL_precondition(divisor != 0); 00583 00584 // Rescale d to have a to_double() value with reasonnable exponent. 00585 exponent_type scale_d = divisor.find_scale(); 00586 divisor.rescale(scale_d); 00587 const double dd = INTERN_MP_FLOAT::to_double(divisor); 00588 00589 MP_Float res = 0; 00590 exponent_type scale_remainder = 0; 00591 00592 bool first_time_smaller_than_divisor = true; 00593 00594 // School division algorithm. 00595 00596 while ( remainder != 0 ) 00597 { 00598 // We have to rescale, since remainder can diminish towards 0. 00599 exponent_type tmp_scale = remainder.find_scale(); 00600 remainder.rescale(tmp_scale); 00601 res.rescale(tmp_scale); 00602 scale_remainder += tmp_scale; 00603 00604 // Compute a double approximation of the quotient 00605 // (imagine school division with base ~2^53). 00606 double approx = INTERN_MP_FLOAT::to_double(remainder) / dd; 00607 CGAL_assertion(approx != 0); 00608 res += approx; 00609 remainder -= approx * divisor; 00610 00611 if (remainder == 0) 00612 break; 00613 00614 // Then we need to fix it up by checking if neighboring double values 00615 // are closer to the exact result. 00616 // There should not be too many iterations, because approx is only a few ulps 00617 // away from the optimal. 00618 // If we don't do the fixup, then spurious bits can be introduced, which 00619 // will require an unbounded amount of additional iterations to be eliminated. 00620 00621 // The direction towards which we need to try to move from "approx". 00622 double direction = (CGAL_NTS sign(remainder) == CGAL_NTS sign(dd)) 00623 ? std::numeric_limits<double>::infinity() 00624 : -std::numeric_limits<double>::infinity(); 00625 00626 while (true) 00627 { 00628 const double approx2 = nextafter(approx, direction); 00629 const double delta = approx2 - approx; 00630 MP_Float new_remainder = remainder - delta * divisor; 00631 if (CGAL_NTS abs(new_remainder) < CGAL_NTS abs(remainder)) { 00632 remainder = new_remainder; 00633 res += delta; 00634 approx = approx2; 00635 } 00636 else { 00637 break; 00638 } 00639 } 00640 00641 if (remainder == 0) 00642 break; 00643 00644 // Test condition for non-exact division (with remainder). 00645 if (compare_bitlength(remainder, divisor) == SMALLER) 00646 { 00647 if (! first_time_smaller_than_divisor) 00648 { 00649 // Scale back. 00650 res.rescale(scale_d - scale_remainder); 00651 remainder.rescale(- scale_remainder); 00652 CGAL_postcondition(res * d + remainder == n); 00653 return std::make_pair(res, remainder); 00654 } 00655 first_time_smaller_than_divisor = false; 00656 } 00657 } 00658 00659 // Scale back the result. 00660 res.rescale(scale_d - scale_remainder); 00661 CGAL_postcondition(res * d == n); 00662 return std::make_pair(res, MP_Float(0)); 00663 } 00664 00665 inline // Move it to libCGAL once it's stable. 00666 bool 00667 divides(const MP_Float & d, const MP_Float & n) 00668 { 00669 return CGALi::division(n, d).second == 0; 00670 } 00671 00672 } // namespace CGALi 00673 00674 inline 00675 bool 00676 is_integer(const MP_Float &m) 00677 { 00678 return m.is_integer(); 00679 } 00680 00681 00682 00683 inline 00684 MP_Float 00685 operator%(const MP_Float& n1, const MP_Float& n2) 00686 { 00687 return CGALi::division(n1, n2).second; 00688 } 00689 00690 00691 // The namespace INTERN_MP_FLOAT contains global functions like square or sqrt 00692 // which collide with the global functor adapting functions provided by the new 00693 // AST/RET concept. 00694 // 00695 // TODO: IMHO, a better solution would be to put the INTERN_MP_FLOAT-functions 00696 // into the MP_Float-class... But there is surely a reason why this is not 00697 // the case..? 00698 00699 00700 namespace INTERN_MP_FLOAT { 00701 inline 00702 MP_Float 00703 div(const MP_Float& n1, const MP_Float& n2) 00704 { 00705 return CGALi::division(n1, n2).first; 00706 } 00707 00708 inline 00709 MP_Float 00710 gcd( const MP_Float& a, const MP_Float& b) 00711 { 00712 if (a == 0) { 00713 if (b == 0) 00714 return 0; 00715 MP_Float tmp=b; 00716 tmp.gcd_normalize(); 00717 return tmp; 00718 } 00719 if (b == 0) { 00720 MP_Float tmp=a; 00721 tmp.gcd_normalize(); 00722 return tmp; 00723 } 00724 00725 MP_Float x = a, y = b; 00726 while (true) { 00727 x = x % y; 00728 if (x == 0) { 00729 CGAL_postcondition(CGALi::divides(y, a) & CGALi::divides(y, b)); 00730 y.gcd_normalize(); 00731 return y; 00732 } 00733 swap(x, y); 00734 } 00735 } 00736 00737 } // INTERN_MP_FLOAT 00738 00739 00740 inline 00741 void 00742 simplify_quotient(MP_Float & numerator, MP_Float & denominator) 00743 { 00744 // Currently only simplifies the two exponents. 00745 #if 0 00746 // This better version causes problems as the I/O is changed for 00747 // Quotient<MP_Float>, which then does not appear as rational 123/345, 00748 // 1.23/3.45, this causes problems in the T2 test-suite (to be investigated). 00749 numerator.exp -= denominator.exp 00750 + (MP_Float::exponent_type) denominator.v.size(); 00751 denominator.exp = - (MP_Float::exponent_type) denominator.v.size(); 00752 #elif 1 00753 numerator.exp -= denominator.exp; 00754 denominator.exp = 0; 00755 #else 00756 if (numerator != 0 && denominator != 0) { 00757 numerator.exp -= denominator.exp; 00758 denominator.exp = 0; 00759 const MP_Float g = gcd(numerator, denominator); 00760 numerator = integral_division(numerator, g); 00761 denominator = integral_division(denominator, g); 00762 } 00763 numerator.exp -= denominator.exp; 00764 denominator.exp = 0; 00765 #endif 00766 } 00767 00768 inline void simplify_root_of_2(MP_Float &/*a*/, MP_Float &/*b*/, MP_Float&/*c*/) { 00769 #if 0 00770 if(is_zero(a)) { 00771 simplify_quotient(b,c); return; 00772 } else if(is_zero(b)) { 00773 simplify_quotient(a,c); return; 00774 } else if(is_zero(c)) { 00775 simplify_quotient(a,b); return; 00776 } 00777 MP_Float::exponent_type va = a.exp + 00778 (MP_Float::exponent_type) a.v.size(); 00779 MP_Float::exponent_type vb = b.exp + 00780 (MP_Float::exponent_type) b.v.size(); 00781 MP_Float::exponent_type vc = c.exp + 00782 (MP_Float::exponent_type) c.v.size(); 00783 MP_Float::exponent_type min = (std::min)((std::min)(va,vb),vc); 00784 MP_Float::exponent_type max = (std::max)((std::max)(va,vb),vc); 00785 MP_Float::exponent_type med = (min+max)/2.0; 00786 a.exp -= med; 00787 b.exp -= med; 00788 c.exp -= med; 00789 #endif 00790 } 00791 00792 namespace CGALi { 00793 inline void simplify_3_exp(int &a, int &b, int &c) { 00794 int min = (std::min)((std::min)(a,b),c); 00795 int max = (std::max)((std::max)(a,b),c); 00796 int med = (min+max)/2; 00797 a -= med; 00798 b -= med; 00799 c -= med; 00800 } 00801 } 00802 00803 00804 // specialization of to double functor 00805 template<> 00806 class Real_embeddable_traits< Quotient<MP_Float> > 00807 : public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< 00808 Quotient<MP_Float> >{ 00809 public: 00810 struct To_double: public std::unary_function<Quotient<MP_Float>, double>{ 00811 inline 00812 double operator()(const Quotient<MP_Float>& q) const { 00813 return INTERN_MP_FLOAT::to_double(q); 00814 } 00815 }; 00816 struct To_interval 00817 : public std::unary_function<Quotient<MP_Float>, std::pair<double,double> > { 00818 inline 00819 std::pair<double,double> operator()(const Quotient<MP_Float>& q) const { 00820 return INTERN_MP_FLOAT::to_interval(q); 00821 } 00822 }; 00823 }; 00824 00825 inline MP_Float min BOOST_PREVENT_MACRO_SUBSTITUTION(const MP_Float& x,const MP_Float& y){ 00826 return (x<=y)?x:y; 00827 } 00828 inline MP_Float max BOOST_PREVENT_MACRO_SUBSTITUTION(const MP_Float& x,const MP_Float& y){ 00829 return (x>=y)?x:y; 00830 } 00831 00832 00833 // TODO: 00834 // // specialization of to double functor 00835 // template<> 00836 // class Real_embeddable_traits< Root_of_2<MP_Float> > 00837 // : public INTERN_ROOT_OF_2::Real_embeddable_traits_quotient_root_of_2_base< 00838 // Root_of_2<MP_Float> >{ 00839 // public: 00840 // struct To_double: public std::unary_function<Root_of_2<MP_Float>, double>{ 00841 // inline 00842 // double operator()(const Root_of_2<MP_Float>& q) const { 00843 // return INTERN_MP_FLOAT::to_double(q); 00844 // } 00845 // }; 00846 // struct To_interval 00847 // : public std::unary_function<Root_of_2<MP_Float>, std::pair<double,double> > { 00848 // inline 00849 // std::pair<double,double> operator()(const Root_of_2<MP_Float>& q) const { 00850 // return INTERN_MP_FLOAT::to_interval(q); 00851 // } 00852 // }; 00853 // }; 00854 00855 // Coercion_traits 00856 CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(MP_Float) 00857 CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int, MP_Float) 00858 00859 00860 CGAL_END_NAMESPACE 00861 00862 #endif // CGAL_MP_FLOAT_H