BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/CORE/BigFloatRep.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: BigFloatRep.h
00019  * Synopsis: 
00020  *              Internal Representation BigFloat.
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/BigFloatRep.h $
00031  * $Id: BigFloatRep.h 37563 2007-03-27 13:28:17Z afabri $
00032  ***************************************************************************/
00033 
00034 #ifndef _CORE_BIGFLOATREP_H_
00035 #define _CORE_BIGFLOATREP_H_
00036 
00037 #include <CGAL/CORE/BigRat.h>
00038 #include <CGAL/CORE/CoreAux.h>
00039 #include <CGAL/CORE/CoreDefs.h>
00040 #include <CGAL/CORE/extLong.h>
00041 
00042 CORE_BEGIN_NAMESPACE
00043 
00044 //  forward reference
00045 class BigFloat;
00046 
00047 //  class BigFloatRep (internal representation for BigFloat)
00048 class BigFloatRep : public RCRepImpl<BigFloatRep> {
00049 public:
00050   static long chunkCeil(long bits);  //inline
00051   static long chunkFloor(long bits); //inline
00052   static long bits(long chunks);     //inline
00053   static BigInt chunkShift(const BigInt& x, long s); //inline
00054   static double lg10(BigInt x);      //inline
00055   static long floorlg10(BigInt x);   //inline
00056 
00058 
00059   static BigFloatRep* exp2(int e);
00060 
00061   struct DecimalOutput;
00062 
00063   friend class BigFloat;
00064 
00065   BigInt        m;
00066   unsigned long err;
00067   long          exp;
00068 
00069 public:
00070   //  constructors
00071   BigFloatRep(int=0);           //inline
00072   BigFloatRep(short);           //inline
00073   BigFloatRep(float);           //inline
00074   BigFloatRep(long);          //inline
00075   BigFloatRep(double);        //inline
00076   BigFloatRep(const BigInt& I, unsigned long u, long l); //inline
00077   BigFloatRep(const BigInt& I, long l); //inline
00078   BigFloatRep(const BigInt& I); //inline
00079   BigFloatRep(const char *);  //inline
00080 
00081   BigRat BigRatize() const;   //inline
00082 
00083   //  the destructor
00084   ~BigFloatRep(); //inline
00085 
00086   CORE_MEMORY(BigFloatRep)    // allocate the memory pool, unless
00087                               // memory pool feature is disabled.
00088 
00089   //  approximation
00090   void trunc(const BigInt&, const extLong&, const extLong&);
00091   void truncM(const BigFloatRep&, const extLong&, const extLong&);
00092   void approx(const BigFloatRep&, const extLong&, const extLong&);
00093 
00094   void div(const BigInt&, const BigInt&, const extLong&, const extLong&);
00095   void approx(const BigRat&, const extLong&, const extLong&); //inline
00096 
00097   //  error-normalization
00098   void eliminateTrailingZeroes(); //inline
00099   void normal();
00100   void bigNormal(BigInt&);
00101 
00102   //  arithmetics
00103 public:
00104   void add(const BigFloatRep&, const BigFloatRep&);
00105   void sub(const BigFloatRep&, const BigFloatRep&);
00106   void mul(const BigFloatRep&, const BigFloatRep&);
00107   void div(const BigFloatRep&, const BigFloatRep&, const extLong&);
00108   void div2(const BigFloatRep&); 
00109 
00110   void centerize(const BigFloatRep&, const BigFloatRep&);
00111 private:
00112   //  squareroot
00113   //    arguments:      r = value whose square root we want
00114   //                    a = absolute precision of the desired result
00115   //                    init = initial approx. to the square root (for Newton)
00116   void sqrt(const BigInt& r, const extLong& a);
00119   void sqrt(const BigInt& r, const extLong& a, const BigFloat& init);
00120   void sqrt(const BigFloatRep& r, const extLong& a);
00123   void sqrt(const BigFloatRep& r, const extLong& a, const BigFloat& init);
00124 
00125   //  comparison
00126   int compareMExp(const BigFloatRep&) const;
00127 
00128   //  builtin functions
00129   extLong lMSB() const;      //inline
00130   extLong uMSB() const;      //inline
00131   extLong MSB() const;       //inline
00132   extLong flrLgErr() const;  //inline
00133   extLong clLgErr() const;   //inline
00134 
00135   bool    isZeroIn() const;  //inline
00136   int     signM() const;     //inline
00137 
00138   //  cast functions
00139   double toDouble() const;
00140   long toLong() const;
00141   BigInt toBigInt() const;
00142 
00143   //  conversion
00144 
00145   // toString() Joaquin Grech 31/5/2003
00146   std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const;
00147   std::string round(std::string inRep, long& L10, unsigned int width) const;
00148   DecimalOutput toDecimal(unsigned int width=defBigFloatOutputDigits,
00149                           bool Scientific=false) const;
00150   void fromString(const char *p, const extLong & prec = defBigFloatInputDigits);
00151 
00152   void dump() const;  //inline
00153   long adjustE(long E, BigInt M, long e) const;
00154 
00155 public:
00156   //  stream operators
00157   std::ostream& operator <<(std::ostream&) const; //inline
00158   std::istream& operator >>(std::istream&);
00159 };//class BigFloatRep
00160 
00162 //  Implementations
00164 
00165 struct BigFloatRep::DecimalOutput {
00166   std::string rep;    // decimal output string
00167   int sign;           // 0, +1 or -1
00168   bool isScientific;  // false=positional notation
00169   int noSignificant;  // number of significant digits
00170   //   -1 means this information is not explicitly
00171   //   given, and must be determined from rep, etc.
00172   bool isExact;       //
00173   int errorCode;      // 0 = no error
00174                       // 1 = sign of number is unknown (e.g., mantissa
00175                       //  is smaller than error)
00176 
00177   DecimalOutput() : rep(""), sign(1), isScientific(false),
00178                     noSignificant(0), isExact(false), errorCode(0) {}
00179 };//DecimalOutput
00180 
00181 // constants used by BigFloatRep
00182 //      NOTES:  CHUNK_BIT is the number of bits in each Chunk
00183 //      Since LONG_BIT = 32 or 64, then CHUNK_BIT = 14 or 30.
00184 //      We have:  0 <= err < 4 * 2^{CHUNK_BIT}
00185 
00186 const long CHUNK_BIT = (long)(LONG_BIT / 2 - 2);        //  chunks
00187 const long HALF_CHUNK_BIT = (CHUNK_BIT + 1) / 2;
00188 const long DBL_MAX_CHUNK = (DBL_MAX_EXP - 1) / CHUNK_BIT + 1;
00189 const double lgTenM = 3.321928094887362;
00190 
00191 inline long BigFloatRep::chunkCeil(long bits) {
00192   if (bits > 0)
00193     return (bits - 1) / CHUNK_BIT + 1;
00194   else
00195     return - (- bits) / CHUNK_BIT;
00196 }//chunkCeil
00197 
00198 inline long BigFloatRep::chunkFloor(long bits) {
00199   if (bits >= 0)
00200     return bits / CHUNK_BIT;
00201   else
00202     return - (- bits - 1) / CHUNK_BIT - 1;
00203 }//chunkFloor
00204 
00205 // bits(c) returns the number of bits in c chunks:
00206 inline long BigFloatRep::bits(long chunks) {
00207   return CHUNK_BIT * chunks;
00208 }
00209 
00210 inline BigInt BigFloatRep::chunkShift(const BigInt& x, long s) {
00211   if (!s || sign(x) == 0)
00212     return x;
00213   else if (s > 0)
00214     //  shift left
00215     if (sign(x) > 0)
00216       return x << static_cast<unsigned long>(bits(s));
00217     else //  x < 0
00218       return - ((-x) << static_cast<unsigned long>(bits(s)));
00219   else //  shift right
00220     if (sign(x) > 0)
00221       return x >> static_cast<unsigned long>(bits(-s));
00222     else //  x < 0
00223       return - ((-x) >> static_cast<unsigned long>(bits(-s)));
00224 }//chunkShift
00225 
00226 inline BigFloatRep* BigFloatRep::exp2(int e) {
00227   long ee;  // this is going to be the exponent
00228   if (e >= 0)
00229     ee = e/CHUNK_BIT;
00230   else
00231     ee = - ((-e + CHUNK_BIT -1)/CHUNK_BIT);
00232 
00233   int rem = e - (ee * CHUNK_BIT);     // Assert: 0 <= rem < CHUNK_BIT
00234 
00235   return new BigFloatRep((1<<rem), 0, ee);
00236   // Here, we assume CHUNK_BIT is less than int width
00237 }
00238 
00239 //  constructors
00240 inline BigFloatRep::BigFloatRep(short n)
00241   : m(n), err(0), exp(0) {}
00242 
00243 inline BigFloatRep::BigFloatRep(float n)
00244   : m(n), err(0), exp(0) {}
00245 
00246 //  Chee (8/8/04) -- introduced constructor from int
00247 inline BigFloatRep::BigFloatRep(int n)
00248   : m(n), err(0), exp(0) {}
00249 
00250 //  Chee (8/8/04) -- introduced constructor from long
00251 inline BigFloatRep::BigFloatRep(long n)
00252   : m(n), err(0), exp(0) {}
00253 
00254 //  Chee (8/8/04) -- introduced constructor from double
00255 /* This turns out to be an alternative implementation of the
00256  * original one in BigFloat.cpp!!
00257 inline BigFloatRep::BigFloatRep(double d)
00258             : m(IntMantissa(d)), err(0), exp(0) {
00259      BigFloatRep * bfr = exp2(IntExponent(d));  // take care of the exponent
00260      m *= bfr->m;
00261      exp = bfr->exp;
00262 }
00263 */
00264 
00265 inline BigFloatRep::BigFloatRep(const BigInt& I, unsigned long er, long ex)
00266   : m(I), err(er), exp(ex) {}
00267 
00268 inline BigFloatRep::BigFloatRep(const BigInt& I)
00269   : m(I), err(0), exp(0) {}
00270 
00271 //Constructs the BigFloat representing I*2^{ex}.
00272 //If ex >=0 then it is clear how to do it.
00273 //Otherwise, let |ex| = CHUNK_BIT * q + r. Then
00274 //I*2^{ex} = I*2^{CHUNK_BIT -r} 2^{-CHUNK_BIT * (q+1)}
00275 inline BigFloatRep::BigFloatRep(const BigInt& I, long ex) {
00276   err=0;
00277   exp = chunkFloor(ex);
00278   if(ex >= 0)
00279     m = I<<(ex - bits(exp));
00280   else{//ex < 0
00281     exp = chunkFloor(abs(ex));
00282     m = I << (CHUNK_BIT - (-ex - bits(exp)));
00283     exp = -1*(1 + exp);
00284   }
00285 }
00286 
00287 inline BigFloatRep::BigFloatRep(const char *str) : m(0), err(0), exp(0) {
00288   fromString(str);
00289 }
00290 
00291 inline BigRat BigFloatRep::BigRatize() const {
00292   if (exp >= 0)
00293     return BigRat(chunkShift(m, exp), 1);
00294   else
00295     return BigRat(m, chunkShift(1, - exp));
00296 }
00297 
00298 //  the destructor
00299 inline BigFloatRep::~BigFloatRep() {}
00300 
00301 inline void BigFloatRep::approx(const BigRat& R, const extLong& r, const extLong& a) {
00302   div(numerator(R), denominator(R), r, a);
00303 }
00304 
00305 //  eliminate trailing zeroes
00306 inline void BigFloatRep::eliminateTrailingZeroes() {
00307   // eliminate trailing 0's    -- IP 10/9/98
00308   /*if (err == 0 && m != 0) {
00309     while ((m & ((1 << CHUNK_BIT) - 1)) == 0) {
00310       m >>= CHUNK_BIT;
00311       exp++;
00312     }
00313   }*/
00314   // new code, much faster, Zilin Du (Nov, 2003)
00315   if (err == 0 && sign(m) != 0) {
00316     int r = getBinExpo(m) / CHUNK_BIT;
00317     m >>= (r * CHUNK_BIT);
00318     exp += r;
00319   }
00320 }
00321 
00322 //  bultin functions
00323 inline extLong BigFloatRep::lMSB() const {
00324   if (!isZeroIn())
00325     return extLong(floorLg(abs(m) - err)) + bits(exp);
00326   else
00327     return extLong(CORE_negInfty);
00328 }
00329 
00331 
00334 inline extLong BigFloatRep::uMSB() const {
00335   return extLong(floorLg(abs(m) + err)) + bits(exp);
00336 }
00337 
00338 inline extLong BigFloatRep::MSB() const {
00339   // Note : MSB is undefined if it's not exact.
00340   if (sign(m))          // sign(m) is non-zero
00341     return extLong(floorLg(m)) + bits(exp);
00342   else
00343     return extLong(CORE_negInfty);
00344 }
00345 
00346 inline extLong BigFloatRep::flrLgErr() const {
00347   if (err)
00348     return extLong(flrLg(err)) + bits(exp);
00349   else
00350     return extLong(CORE_negInfty);
00351 }
00352 
00353 inline extLong BigFloatRep::clLgErr() const {
00354   if (err)
00355     return extLong(clLg(err)) + bits(exp);
00356   else
00357     return extLong(CORE_negInfty);
00358 }
00359 
00360 // isZero() = true iff zero is inside the interval of BigFloat:
00361 inline bool BigFloatRep::isZeroIn() const {
00362   if (err == 0){
00363     return (m == 0);    //Nov 6, 2002: bug fix!
00364   }
00365   long lm = bitLength(m);
00366   if (lm > CHUNK_BIT+2) {
00367     return false;   // since err < 4 * 2^{CHUNK_BIT}
00368   } else {
00369     return (abs(m) <= BigInt(err));
00370   }
00371 }
00372 
00373 inline int BigFloatRep::signM() const {
00374   return sign(m);
00375 }
00376 
00377 inline double BigFloatRep::lg10(BigInt x) {
00378   if (x == 0)
00379     return 0;
00380 
00381   BigInt t(abs(x));
00382   long l = -1;
00383   double d = 0;
00384 
00385   while (t > 0) {
00386     l++;
00387     d /= 10;
00388     d += ulongValue(t%10);
00389     t /= 10;
00390   }
00391   return std::log10(d) + l;
00392 }
00393 
00394 // this is a simpler form of lg10()
00395 inline long BigFloatRep::floorlg10(BigInt x) {
00396   if (x == 0)
00397     return 0;
00398   BigInt t(abs(x));
00399   long l = -1;
00400 
00401   while (t > 0) {
00402     l++;
00403     t /= 10;
00404   }
00405   return l;
00406 }
00407 
00408 inline std::ostream& BigFloatRep::operator<<(std::ostream& o) const {
00409   bool sci = (o.flags() & std::ios::scientific) > 0;
00410   BigFloatRep::DecimalOutput r = toDecimal(o.precision(), sci);
00411   if (r.sign == -1)
00412     o << "-";
00413   o << r.rep;
00414   return o;
00415 }
00416 
00417 /* Returns a std::string with precision and format specified
00418    Works as cout << with the exception that if the output
00419    contains any error it returns a NULL
00420    Joaquin Grech 31/5/03
00421    */
00422 inline std::string BigFloatRep::toString(long prec, bool sci) const {
00423   BigFloatRep::DecimalOutput r = toDecimal(prec, sci);
00424 
00425   if (r.errorCode == 0) {
00426     if (r.sign < 0)
00427       return std::string("-")+r.rep;
00428     else
00429       return r.rep;
00430   }
00431   return NULL;
00432 }
00433 
00434 inline void BigFloatRep::dump() const {
00435   std::cout << "---- BFRep: " << this << " ----" << std::endl;
00436   std::cout << "  BF value: ";
00437   this->operator<<(std::cout);
00438   std::cout <<  std::endl;
00439   std::cout << "  m = " << m << std::endl;
00440   std::cout << "  err = " << err << std::endl;
00441   std::cout << "  exp = " << exp << std::endl;
00442   std::cout << " -- End of BFRep " << this << " -- " << std::endl;
00443 }
00444 
00445 CORE_END_NAMESPACE
00446 #endif // _CORE_BIGFLOATREP_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines