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