BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/MP_Float.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines