BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/CORE/BigFloat.h
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Core Library Version 1.7, August 2004
00003  * Copyright (c) 1995-2004 Exact Computation Project
00004  * All rights reserved.
00005  *
00006  * This file is part of CORE (http://cs.nyu.edu/exact/core/); you may
00007  * redistribute it under the terms of the Q Public License version 1.0.
00008  * See the file LICENSE.QPL distributed with CORE.
00009  *
00010  * Licensees holding a valid commercial license may use this file in
00011  * accordance with the commercial license agreement provided with the
00012  * software.
00013  *
00014  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00015  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00016  *
00017  *
00018  * File: BigFloat.h
00019  * Synopsis: 
00020  *              An implementation of BigFloat numbers with error bounds.
00021  * 
00022  * Written by 
00023  *       Chee Yap <yap@cs.nyu.edu>
00024  *       Chen Li <chenli@cs.nyu.edu>
00025  *       Zilin Du <zilin@cs.nyu.edu>
00026  *
00027  * WWW URL: http://cs.nyu.edu/exact/
00028  * Email: exact@cs.nyu.edu
00029  *
00030  * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/BigFloat.h $
00031  * $Id: BigFloat.h 37563 2007-03-27 13:28:17Z afabri $
00032  ***************************************************************************/
00033 
00034 #ifndef _CORE_BIGFLOAT_H_
00035 #define _CORE_BIGFLOAT_H_
00036 
00037 #include <CGAL/CORE/BigFloatRep.h>
00038 
00039 CORE_BEGIN_NAMESPACE
00040 
00041 class Expr;
00042 
00045 typedef RCImpl<BigFloatRep> RCBigFloat;
00046 class BigFloat : public RCBigFloat {
00047 public:
00049 
00050 
00051   BigFloat() : RCBigFloat(new BigFloatRep()) {}
00053   BigFloat(short i) : RCBigFloat(new BigFloatRep(i)) {}
00055   BigFloat(float i) : RCBigFloat(new BigFloatRep(i)) {}
00057   BigFloat(int i) : RCBigFloat(new BigFloatRep(i)) {}
00059   BigFloat(long l) : RCBigFloat(new BigFloatRep(l)) {}
00061   BigFloat(double d) : RCBigFloat(new BigFloatRep(d)) {}
00063   BigFloat(const char* s) : RCBigFloat(new BigFloatRep(s)) {}
00065   BigFloat(const std::string& s) : RCBigFloat(new BigFloatRep(s)) {}
00066 
00068   //     This is a hack because in Sturm, we need to approximate any
00069   //     coefficient type NT to a BigFloat, and it would complain if we
00070   //     do not have this method explicitly:
00071   BigFloat(int& i, const extLong& /*r*/, const extLong& /*a*/)
00072       : RCBigFloat(new BigFloatRep(i)) {}
00073   BigFloat(long& x, const extLong& /*r*/, const extLong& /*a*/)
00074       : RCBigFloat(new BigFloatRep(x)) {}
00076   BigFloat(const BigInt& I, unsigned long er, long ex)
00077       : RCBigFloat(new BigFloatRep(I, er, ex)) {}
00079   BigFloat(const BigInt& I, long ex)
00080       : RCBigFloat(new BigFloatRep(I, ex)) {}
00081   BigFloat(const BigInt& I)
00082       : RCBigFloat(new BigFloatRep(I)) {}
00084   BigFloat(const BigRat& R, const extLong& r = defRelPrec,
00085            const extLong& a = defAbsPrec)
00086       : RCBigFloat(new BigFloatRep()) {
00087     rep->approx(R, r, a);
00088   }
00089 
00090   // REMARK: it is somewhat against our principles to have BigFloat
00091   // know about Expr, but BigFloat has a special role in our system!
00092   // ===============================
00094   explicit BigFloat(const Expr& E, const extLong& r = defRelPrec,
00095            const extLong& a = defAbsPrec);
00096 
00097   //Dummy
00098   explicit BigFloat(const BigFloat& E, const extLong& ,
00099            const extLong&): RCBigFloat(E) {
00100     rep->incRef();
00101   }
00102 
00104   explicit BigFloat(BigFloatRep* r) : RCBigFloat(new BigFloatRep()) {
00105     rep = r;
00106   }
00108 
00110 
00111 
00112   BigFloat(const BigFloat& rhs) : RCBigFloat(rhs) {
00113     rep->incRef();
00114   }
00116   BigFloat& operator=(const BigFloat& rhs) {
00117     if (this != &rhs) {
00118       rep->decRef();
00119       rep = rhs.rep;
00120       rep->incRef();
00121     }
00122     return *this;
00123   }
00125   ~BigFloat() {
00126     rep->decRef();
00127   }
00129 
00131 
00132 
00133   BigFloat& operator+= (const BigFloat& x) {
00134     BigFloat z;
00135     z.rep->add(*rep, *x.rep);
00136     *this = z;
00137     return *this;
00138   }
00140   BigFloat& operator-= (const BigFloat& x) {
00141     BigFloat z;
00142     z.rep->sub(*rep, *x.rep);
00143     *this = z;
00144     return *this;
00145   }
00147   BigFloat& operator*= (const BigFloat& x) {
00148     BigFloat z;
00149     z.rep->mul(*rep, *x.rep);
00150     *this = z;
00151     return *this;
00152   }
00154   BigFloat& operator/= (const BigFloat& x) {
00155     BigFloat z;
00156     z.rep->div(*rep, *x.rep, defBFdivRelPrec);
00157     *this = z;
00158     return *this;
00159   }
00161 
00163 
00164 
00165   BigFloat operator+() const {
00166     return BigFloat(*this);
00167   }
00169   BigFloat operator-() const {
00170     return BigFloat(-rep->m, rep->err, rep->exp);
00171   }
00173 
00175 
00176 
00177   void fromString(const char* s, const extLong& p=defBigFloatInputDigits) {
00178     rep->fromString(s, p);
00179   }
00181   std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const {
00182     return rep->toString(prec, sci);
00183   }
00184   std::string str() const {
00185     return toString();
00186   }
00188 
00190 
00191 
00192   int intValue() const {
00193     return static_cast<int>(rep->toLong());
00194   }
00196   long longValue() const {
00197     long l = rep->toLong();
00198     if ((l == LONG_MAX) || (l == LONG_MIN))
00199       return l; // return the overflown value.
00200     if ((sign() < 0) && (cmp(BigFloat(l)) != 0)) {
00201       // a negative value not exactly rounded.
00202       l--; // rounded to floor.
00203     }
00204     return l;
00205   }
00207   float floatValue() const {
00208     return static_cast<float>(rep->toDouble());
00209   }
00211   double doubleValue() const {
00212     return rep->toDouble();
00213   }
00215   BigInt BigIntValue() const {
00216     return rep->toBigInt();
00217   }
00219   BigRat BigRatValue() const {
00220     return rep->BigRatize();
00221   }
00223 
00225 
00226 
00227   static bool hasExactDivision() {
00228     return false;
00229   }
00230   
00231   //CONSTANTS
00233   static const BigFloat& getZero();
00235   static const BigFloat& getOne();
00236 
00238 
00240   int sign() const {
00241     assert((err() == 0 && m() == 0) || !(isZeroIn()));
00242     return rep->signM();
00243   }
00245 
00246   bool isZeroIn() const {
00247     return rep->isZeroIn();
00248   }
00250   BigFloat abs() const {
00251     return (sign()>0) ? +(*this) : -(*this);
00252   }
00254   int cmp(const BigFloat& x) const {
00255     return rep->compareMExp(*x.rep);
00256   }
00257 
00259   const BigInt& m() const {
00260     return rep->m;
00261   }
00263   unsigned long err() const {
00264     return rep->err;
00265   }
00267   long exp() const {
00268     return rep->exp;
00269   }
00270 
00272 
00273   bool isExact() const {
00274     return rep->err == 0;
00275   }
00277 
00278   BigFloat& makeExact() {
00279     makeCopy();
00280     rep->err =0;
00281     return *this;
00282   }
00284 
00285   BigFloat& makeCeilExact() {
00286     makeCopy();
00287     rep->m += rep->err;
00288     rep->err =0;
00289     return *this;
00290   }
00292 
00293   BigFloat& makeFloorExact() {
00294     makeCopy();
00295     rep->m -= rep->err;
00296     rep->err =0;
00297     return *this;
00298   }
00300 
00301   BigFloat& makeInexact() {
00302     makeCopy();
00303     rep->err =1;
00304     return *this;
00305   }
00306 
00308   extLong lMSB() const {
00309     return rep->lMSB();
00310   }
00312   extLong uMSB() const {
00313     return rep->uMSB();
00314   }
00316   extLong MSB() const {
00317     return rep->MSB();
00318   }
00319 
00321   extLong flrLgErr() const {
00322     return rep->flrLgErr();
00323   }
00325   extLong clLgErr() const {
00326     return rep->clLgErr();
00327   }
00328 
00330   BigFloat div(const BigFloat& x, const extLong& r) const {
00331     BigFloat y;
00332     y.rep->div(*rep, *x.rep, r);
00333     return y;
00334   }
00336   BigFloat div2() const {
00337     BigFloat y;
00338     y.rep->div2(*rep);
00339     return y;
00340   }
00341 
00343   BigFloat sqrt(const extLong& a) const {
00344     BigFloat x;
00345     x.rep->sqrt(*rep, a);
00346     return x;
00347   }
00349   BigFloat sqrt(const extLong& a, const BigFloat& init) const {
00350     BigFloat x;
00351     x.rep->sqrt(*rep, a, init);
00352     return x;
00353   }
00355 
00357 
00358 
00359   void approx(const BigInt& I, const extLong& r, const extLong& a) {
00360     makeCopy();
00361     rep->trunc(I, r, a);
00362   }
00364   void approx(const BigFloat& B, const extLong& r, const extLong& a) {
00365     makeCopy();
00366     rep->approx(*B.rep, r, a);
00367   }
00369   void approx(const BigRat& R, const extLong& r, const extLong& a) {
00370     makeCopy();
00371     rep->approx(R, r, a);
00372   }
00374   void dump() const {
00375     rep->dump();
00376   }
00378 
00380   static BigFloat exp2(int e) {
00381     return BigFloat(BigFloatRep::exp2(e));
00382   }
00383 
00384 }; // class BigFloat
00385 
00387 
00389 
00390 
00391 void readFromFile(BigFloat& bf, std::istream& in, long maxLength = 0);
00393 void writeToFile(const BigFloat& bf, std::ostream& in,
00394                 int base=10, int charsPerLine=80);
00395 
00397 inline std::ostream& operator<< (std::ostream& o, const BigFloat& x) {
00398   x.getRep().operator<<(o);
00399   return o;
00400 }
00402 inline std::istream& operator>> (std::istream& i, BigFloat& x) {
00403   x.makeCopy();
00404   x.getRep().operator>>(i);
00405   return i;
00406 }
00408 
00410 inline BigFloat operator+ (const BigFloat& x, const BigFloat& y) {
00411   BigFloat z;
00412   z.getRep().add(x.getRep(), y.getRep());
00413   return z;
00414 }
00416 inline BigFloat operator- (const BigFloat& x, const BigFloat& y) {
00417   BigFloat z;
00418   z.getRep().sub(x.getRep(), y.getRep());
00419   return z;
00420 }
00422 inline BigFloat operator* (const BigFloat& x, const BigFloat& y) {
00423   BigFloat z;
00424   z.getRep().mul(x.getRep(), y.getRep());
00425   return z;
00426 }
00428 inline BigFloat operator/ (const BigFloat& x, const BigFloat& y) {
00429   BigFloat z;
00430   z.getRep().div(x.getRep(),y.getRep(),defBFdivRelPrec);
00431   return z;
00432 }
00433 
00435 inline bool operator== (const BigFloat& x, const BigFloat& y) {
00436   return x.cmp(y) == 0;
00437 }
00439 inline bool operator!= (const BigFloat& x, const BigFloat& y) {
00440   return x.cmp(y) != 0;
00441 }
00443 inline bool operator>= (const BigFloat& x, const BigFloat& y) {
00444   return x.cmp(y) >= 0;
00445 }
00447 inline bool operator> (const BigFloat& x, const BigFloat& y) {
00448   return x.cmp(y) > 0;
00449 }
00451 inline bool operator<= (const BigFloat& x, const BigFloat& y) {
00452   return x.cmp(y) <= 0;
00453 }
00455 inline bool operator< (const BigFloat& x, const BigFloat& y) {
00456   return x.cmp(y) < 0;
00457 }
00458 
00460 inline int sign(const BigFloat& x) {
00461   return x.sign();
00462 }
00464 inline BigFloat div2(const BigFloat& x){
00465   return x.div2();
00466 }
00468 inline BigFloat abs(const BigFloat& x) {
00469   return x.abs();
00470 }
00472 inline int cmp(const BigFloat& x, const BigFloat& y) {
00473   return x.cmp(y);
00474 }
00476 BigFloat pow(const BigFloat&, unsigned long);
00478 inline BigFloat power(const BigFloat& x, unsigned long p) {
00479   return pow(x, p);
00480 }
00483 BigFloat root(const BigFloat&, unsigned long k, const extLong&, const BigFloat&);
00484 inline BigFloat root(const BigFloat& x, unsigned long k) {
00485   return root(x, k, defBFsqrtAbsPrec, x);
00486 }
00487 
00489 inline BigFloat sqrt(const BigFloat& x) {
00490   return x.sqrt(defBFsqrtAbsPrec);
00491 }
00492 
00494 inline BigFloat centerize(const BigFloat& a, const BigFloat& b) {
00495   BigFloat z;
00496   z.getRep().centerize(a.getRep(), b.getRep());
00497   return z;
00498 }
00499 
00501 inline long minStar(long m, long n) {
00502   if (m*n <= 0) return 0;
00503   if (m>0) 
00504     return core_min(m, n);
00505   else 
00506     return core_max(m, n);
00507 }
00509 
00510 
00511 
00516 inline bool isDivisible(const BigFloat& a, const BigFloat& b) {
00517   // assert: a and b are exact BigFloats.
00518   if (sign(a.m()) == 0) return true;
00519   if (sign(b.m()) == 0) return false;
00520   unsigned long bin_a = getBinExpo(a.m());
00521   unsigned long bin_b = getBinExpo(b.m());
00522   
00523   BigInt m_a = a.m() >> bin_a;
00524   BigInt m_b = b.m() >> bin_b;
00525   long e_a = bin_a + BigFloatRep::bits(a.exp());
00526   long e_b = bin_b + BigFloatRep::bits(b.exp());
00527   long dx = minStar(e_a, e_b);
00528 
00529   return isDivisible(m_a, m_b) && (dx == e_b); 
00530 }
00531 
00532 inline bool isDivisible(double x, double y) {
00533   //Are these exact?
00534   return isDivisible(BigFloat(x), BigFloat(y)); 
00535 }
00536 
00538 
00540 // Chee (8/1/2004)   The definition of div_exact(x,y) 
00541 //   ensure that Polynomials<NT> works with NT=BigFloat and NT=double.
00542 //Bug: We should first normalize the mantissas of the Bigfloats and
00543 //then do the BigInt division. For e.g. 1 can be written as 2^{14}*2{-14}.
00544 //Now if we divide 2 by one using this representation of one and without
00545 // normalizing it then we get zero.
00546 inline BigFloat div_exact(const BigFloat& x, const BigFloat& y) {
00547   BigInt z;
00548   assert (isDivisible(x,y));
00549   unsigned long bin_x = getBinExpo(x.m());
00550   unsigned long bin_y = getBinExpo(y.m());
00551 
00552   BigInt m_x = x.m() >> bin_x;
00553   BigInt m_y = y.m() >> bin_y;
00554   long e_x = bin_x + BigFloatRep::bits(x.exp());
00555   long e_y = bin_y + BigFloatRep::bits(y.exp());
00556   //Since y divides x, e_y = minstar(e_x, e_y)
00557   z = div_exact(m_x, m_y);
00558 
00559   //  mpz_divexact(z.get_mp(), x.m().get_mp(), y.m().get_mp()); THIS WAS THE BUG
00560   // assert: x.exp() - y.exp() does not under- or over-flow.
00561   return BigFloat(z, e_x - e_y);  
00562 }
00563 
00564 inline BigFloat div_exact(double x, double y) {
00565   return div_exact(BigFloat(x), BigFloat(y));
00566 }
00567 // Remark: there is another notion of "exact division" for BigFloats,
00568 //      and that is to make the division return an "exact" BigFloat
00569 //      i.e., err()=0.  
00570 
00572 inline BigFloat gcd(const BigFloat& a, const BigFloat& b) {
00573   if (sign(a.m()) == 0) return core_abs(b);
00574   if (sign(b.m()) == 0) return core_abs(a);
00575 
00576   BigInt r;
00577   long dx;
00578   unsigned long bin_a = getBinExpo(a.m());
00579   unsigned long bin_b = getBinExpo(b.m());
00580 
00581 /* THE FOLLOWING IS ALTERNATIVE CODE, for GCD using base B=2^{14}:
00582  *std::cout << "bin_a=" << bin_a << ",bin_b=" << bin_b << std::endl;
00583   std::cout << "a.exp()=" << a.exp() << ",b.exp()=" << b.exp() << std::endl;
00584   long chunk_a = BigFloatRep::chunkFloor(bin_a);
00585   long chunk_b = BigFloatRep::chunkFloor(bin_b);
00586   BigInt m_a = BigFloatRep::chunkShift(a.m(), chunk_a);
00587   BigInt m_b = BigFloatRep::chunkShift(b.m(), chunk_b);
00588 
00589   r = gcd(m_a, m_b);
00590   dx = minStar(chunk_a + a.exp(), chunk_b + b.exp());
00591 */
00592   BigInt m_a = a.m() >> bin_a;
00593   BigInt m_b = b.m() >> bin_b;
00594   r = gcd(m_a, m_b);
00595   dx = minStar(bin_a + BigFloatRep::bits(a.exp()),
00596                   bin_b + BigFloatRep::bits(b.exp()));
00597 
00598   long chunks = BigFloatRep::chunkFloor(dx);
00599   r <<= (dx - BigFloatRep::bits(chunks));
00600   dx = chunks;
00601 
00602   return BigFloat(r, 0, dx);
00603 }
00604 
00605 // Not needed for now:
00607 // inline void div_rem(BigFloat& q, BigFloat& r,
00608 //      const BigFloat& a, const BigFloat& b) {
00609   //q.makeCopy();
00610   //r.makeCopy();
00611   //mpz_tdiv_qr(q.get_mp(), r.get_mp(), a.get_mp(), b.get_mp());
00612 //}//
00613 
00614 
00615 // constructor BigRat from BigFloat
00616 inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){
00617   *this = f.BigRatValue();
00618 }
00619 CORE_END_NAMESPACE
00620 #endif // _CORE_BIGFLOAT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines