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: Real.h 00019 * 00020 * Synopsis: The Real class is a superclass for all the number 00021 * systems in the Core Library (int, long, float, double, 00022 * BigInt, BigRat, BigFloat, etc) 00023 * 00024 * Written by 00025 * Koji Ouchi <ouchi@simulation.nyu.edu> 00026 * Chee Yap <yap@cs.nyu.edu> 00027 * Chen Li <chenli@cs.nyu.edu> 00028 * Zilin Du <zilin@cs.nyu.edu> 00029 * Sylvain Pion <pion@cs.nyu.edu> 00030 * 00031 * WWW URL: http://cs.nyu.edu/exact/ 00032 * Email: exact@cs.nyu.edu 00033 * 00034 * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/Real.h $ 00035 * $Id: Real.h 28567 2006-02-16 14:30:13Z lsaboret $ 00036 ***************************************************************************/ 00037 #ifndef _CORE_REAL_H_ 00038 #define _CORE_REAL_H_ 00039 #include "RealRep.h" 00040 00041 CORE_BEGIN_NAMESPACE 00042 // class Real 00043 typedef RCImpl<RealRep> RCReal; 00044 class Real : public RCReal { 00045 public: 00046 Real(int i=0) : RCReal(new RealLong(i)) {} 00047 Real(unsigned int ui) : RCReal(NULL) { 00048 (ui<=INT_MAX) ? (rep=new RealLong(static_cast<int>(ui))) : (rep=new RealBigInt(ui)); 00049 } 00050 Real(long l) : RCReal(new RealLong(l)) {} 00051 Real(unsigned long ul) : RCReal(NULL) { 00052 (ul<=LONG_MAX) ? (rep=new RealLong(static_cast<long>(ul))) : (rep=new RealBigInt(ul)); 00053 } 00054 Real(float f) : RCReal(new RealDouble(f)) {} 00055 Real(double d) : RCReal(new RealDouble(d)) {} 00056 Real(const BigInt& I) : RCReal(new RealBigInt(I)) {} 00057 Real(const BigRat& R) : RCReal(new RealBigRat(R)) {} 00058 Real(const BigFloat& F) : RCReal(new RealBigFloat(F)) {} 00059 Real(const char* s, const extLong& prec=defInputDigits) : RCReal(NULL) { 00060 constructFromString(s, prec); 00061 } 00062 Real(const std::string& s, const extLong& prec=defInputDigits) : RCReal(NULL){ 00063 constructFromString(s.c_str(), prec); 00064 } 00065 00067 00068 00069 Real(const Real& rhs) : RCReal(rhs) { 00070 rep->incRef(); 00071 } 00073 Real& operator=(const Real& rhs) { 00074 if (this != &rhs) { 00075 rep->decRef(); 00076 rep = rhs.rep; 00077 rep->incRef(); 00078 } 00079 return *this; 00080 } 00082 ~Real() { 00083 rep->decRef(); 00084 } 00086 00088 00089 00090 Real& operator+=(const Real& x); 00092 Real& operator-=(const Real& x); 00094 Real& operator*=(const Real& x); 00096 Real& operator/=(const Real& x); 00098 00100 00101 00102 Real operator+() const { 00103 return Real(*this); 00104 } 00106 Real operator-() const { 00107 return -(*rep); 00108 } 00110 Real& operator++() { 00111 *this += 1; 00112 return *this; 00113 } 00115 Real& operator--() { 00116 *this -= 1; 00117 return *this; 00118 } 00120 Real operator++(int) { 00121 Real t(*this); 00122 *this += 1; 00123 return t; 00124 } 00126 Real operator--(int) { 00127 Real t(*this); 00128 *this -= 1; 00129 return t; 00130 } 00132 00134 00135 00136 void fromString(const char* s, const extLong& prec = defInputDigits) { 00137 *this = Real(s, prec); 00138 } 00140 00141 std::string toString(long prec=defOutputDigits, bool sci=false) const { 00142 return rep->toString(prec, sci); 00143 } 00145 00147 00148 00149 int intValue() const { 00150 return static_cast<int>(longValue()); 00151 } 00153 long longValue() const { 00154 return rep->longValue(); 00155 } 00157 float floatValue() const { 00158 return static_cast<float>(doubleValue()); 00159 } 00161 double doubleValue() const { 00162 return rep->doubleValue(); 00163 } 00165 BigInt BigIntValue() const { 00166 return rep->BigIntValue(); 00167 } 00169 BigRat BigRatValue() const { 00170 return rep->BigRatValue(); 00171 } 00173 BigFloat BigFloatValue() const { 00174 return rep->BigFloatValue(); 00175 } 00177 00179 00180 00181 Real approx(const extLong& r=defRelPrec, const extLong& a=defAbsPrec) const { 00182 return rep->approx(r, a); 00183 } 00185 00187 00188 00189 int sign() const { 00190 return rep->sgn(); 00191 } 00193 bool isZero() const { 00194 return sign() == 0; 00195 } 00197 bool isZeroIn() const { 00198 return rep->isZeroIn(); 00199 } 00201 Real abs() const { 00202 return (sign() >= 0) ? +(*this) : -(*this); 00203 } 00204 00206 BigInt getMantissa() const { 00207 return BigFloatValue().m(); 00208 } 00210 long getExponent() const { 00211 return BigFloatValue().exp(); 00212 } 00213 00215 bool isExact() const { 00216 return rep->isExact(); 00217 } 00218 00220 extLong lMSB() const { 00221 return isExact() ? MSB():(rep->BigFloatValue()).lMSB(); 00222 } 00224 extLong uMSB() const { 00225 return isExact() ? MSB():(rep->BigFloatValue()).uMSB(); 00226 } 00228 extLong MSB() const { 00229 return rep->mostSignificantBit; 00230 } 00231 00233 extLong flrLgErr() const { 00234 return rep->flrLgErr(); 00235 } 00237 extLong clLgErr() const { 00238 return rep->clLgErr(); 00239 } 00240 00242 Real div(const Real& x, const extLong& r) const; 00244 Real sqrt(const extLong& x) const { 00245 return rep->sqrt(x); 00246 } 00248 Real sqrt(const extLong& x, const BigFloat& A) const { 00249 return rep->sqrt(x, A); 00250 } 00251 00253 void ULV_E(extLong &up, extLong &lp, extLong &v2p, extLong &v2m, 00254 extLong &v5p, extLong &v5m) const { 00255 rep->ULV_E(up, lp, v2p, v2m, v5p, v5m); 00256 } 00257 00259 unsigned long degree() const { 00260 return rep->degree(); 00261 } 00263 unsigned long length() const { 00264 return rep->length(); 00265 } 00267 unsigned long height() const { 00268 return rep->height(); 00269 } 00271 00273 static const Real& getZero(); 00274 private: 00275 void constructFromString(const char *str, const extLong& prec); 00276 }; 00277 00278 #define CORE_REAL_ZERO Real::getZero() 00279 00280 const long halfLongMax = LONG_MAX /2; 00281 const long halfLongMin = LONG_MIN /2; 00282 00283 struct _real_add { 00284 template <class T> 00285 static Real eval(const T& a, const T& b) { 00286 return a+b; 00287 } 00288 // specialized for two long values 00289 static Real eval(long a, long b) { 00290 if ((a > halfLongMax && b > halfLongMax) || (a < halfLongMin && b < halfLongMin)) 00291 return BigInt(a)+BigInt(b); 00292 else 00293 return a+b; 00294 } 00295 }; 00296 00297 struct _real_sub { 00298 template <class T> 00299 static Real eval(const T& a, const T& b) { 00300 return a-b; 00301 } 00302 // specialized for two long values 00303 static Real eval(long a, long b) { 00304 if ((a > halfLongMax && b < halfLongMin) || (a < halfLongMin && b > halfLongMax)) 00305 return BigInt(a)-BigInt(b); 00306 else 00307 return a-b; 00308 } 00309 }; 00310 00311 struct _real_mul { 00312 template <class T> 00313 static Real eval(const T& a, const T& b) { 00314 return a*b; 00315 } 00316 // specialized for two long values 00317 static Real eval(long a, long b) { 00318 if (flrLg(a) + flrLg(b) >= static_cast<int>(LONG_BIT-2)) 00319 return BigInt(a)*BigInt(b); 00320 else 00321 return a*b; 00322 } 00323 }; 00324 00325 template <class Op> 00326 struct _real_binary_op { 00327 static Real eval(const RealRep& a, const RealRep& b) { 00328 if (a.ID() == REAL_BIGRAT || b.ID() == REAL_BIGRAT) { 00329 if (!a.isExact()) { // a must be a BigFloat and b must be a BigRat 00330 BigFloat bf_a = a.BigFloatValue(), bf_b; 00331 bf_b.approx(b.BigRatValue(), CORE_posInfty, -bf_a.flrLgErr()); 00332 return Op::eval(bf_a, bf_b); 00333 } else if (!b.isExact()) { // a must be a BigRat and b must be a BigFloat 00334 BigFloat bf_a, bf_b = b.BigFloatValue(); 00335 bf_a.approx(a.BigRatValue(), CORE_posInfty, -bf_b.flrLgErr()); 00336 return Op::eval(bf_a, bf_b); 00337 } else // both are BigRat 00338 return Op::eval(a.BigRatValue(), b.BigRatValue()); 00339 } else if (a.ID() == REAL_BIGFLOAT || b.ID() == REAL_BIGFLOAT 00340 || a.ID() == REAL_DOUBLE || b.ID() == REAL_DOUBLE) { 00341 return Op::eval(a.BigFloatValue(), b.BigFloatValue()); 00342 } else if (a.ID() == REAL_BIGINT || b.ID() == REAL_BIGINT) { 00343 return Op::eval(a.BigIntValue(), b.BigIntValue()); 00344 } else { // a.ID() == REAL_LONG && b.ID() == REAL_LONG 00345 return Op::eval(a.longValue(), b.longValue()); 00346 } 00347 } 00348 }; 00349 00350 typedef _real_binary_op<_real_add> real_add; 00351 typedef _real_binary_op<_real_sub> real_sub; 00352 typedef _real_binary_op<_real_mul> real_mul; 00353 00354 struct real_div { 00355 static Real eval(const RealRep& a, const RealRep& b, const extLong& r) { 00356 if (a.ID() == REAL_BIGRAT || b.ID() == REAL_BIGRAT) { 00357 if (!a.isExact()) { // a must be a BigFloat and b must be a BigRat 00358 BigFloat bf_a = a.BigFloatValue(), bf_b; 00359 bf_b.approx(b.BigRatValue(), bf_a.MSB() - bf_a.flrLgErr() + 1, CORE_posInfty); 00360 return bf_a.div(bf_b, r); 00361 } else if (!b.isExact()) { // a must be a BigRat and b must be a BigFloat 00362 BigFloat bf_a, bf_b = b.BigFloatValue(); 00363 bf_a.approx(a.BigRatValue(), bf_b.MSB() - bf_b.flrLgErr() + 1, CORE_posInfty); 00364 return bf_a.div(bf_b, r); 00365 } else // both are BigRat 00366 return a.BigRatValue()/b.BigRatValue(); 00367 } else if (a.ID() == REAL_BIGFLOAT || b.ID() == REAL_BIGFLOAT 00368 || a.ID() == REAL_DOUBLE || b.ID() == REAL_DOUBLE) { 00369 return a.BigFloatValue().div(b.BigFloatValue(), r); 00370 } else if (a.ID() == REAL_BIGINT || b.ID() == REAL_BIGINT) { 00371 return BigRat(a.BigIntValue(), b.BigIntValue()); 00372 } else { // a.ID() == REAL_LONG && b.ID() == REAL_LONG 00373 return BigRat(a.longValue(), b.longValue()); 00374 } 00375 } 00376 }; 00377 00378 std::istream& operator>>(std::istream& i, Real& r); 00379 inline std::ostream& operator<<(std::ostream& o, const Real& r) { 00380 return r.getRep().operator<<(o); 00381 } 00382 00383 inline Real& Real::operator+=(const Real& rhs) { 00384 *this = real_add::eval(getRep(), rhs.getRep()); 00385 return *this; 00386 } 00387 inline Real& Real::operator-=(const Real& rhs) { 00388 *this = real_sub::eval(getRep(), rhs.getRep()); 00389 return *this; 00390 } 00391 inline Real& Real::operator*=(const Real& rhs) { 00392 *this = real_mul::eval(getRep(), rhs.getRep()); 00393 return *this; 00394 } 00395 inline Real& Real::operator/=(const Real& rhs) { 00396 *this = real_div::eval(getRep(), rhs.getRep(), defRelPrec); 00397 return *this; 00398 } 00399 00400 // operator+ 00401 inline Real operator+(const Real& x, const Real& y) { 00402 return real_add::eval(x.getRep(), y.getRep()); 00403 } 00404 // operator- 00405 inline Real operator-(const Real& x, const Real& y) { 00406 return real_sub::eval(x.getRep(), y.getRep()); 00407 } 00408 // operator* 00409 inline Real operator*(const Real& x, const Real& y) { 00410 return real_mul::eval(x.getRep(), y.getRep()); 00411 } 00412 // operator/ 00413 inline Real operator/(const Real& x, const Real& y) { 00414 return real_div::eval(x.getRep(), y.getRep(), defRelPrec); 00415 } 00416 // div w/ precision 00417 inline Real Real::div(const Real& x, const extLong& r) const { 00418 return real_div::eval(getRep(), x.getRep(), r); 00419 } 00420 00421 inline int cmp(const Real& x, const Real& y) { 00422 return (x-y).sign(); 00423 } 00424 inline bool operator==(const Real& x, const Real& y) { 00425 return cmp(x, y) == 0; 00426 } 00427 inline bool operator!=(const Real& x, const Real& y) { 00428 return cmp(x, y) != 0; 00429 } 00430 inline bool operator>=(const Real& x, const Real& y) { 00431 return cmp(x, y) >= 0; 00432 } 00433 inline bool operator>(const Real& x, const Real& y) { 00434 return cmp(x, y) > 0; 00435 } 00436 inline bool operator<=(const Real& x, const Real& y) { 00437 return cmp(x, y) <= 0; 00438 } 00439 inline bool operator<(const Real& x, const Real& y) { 00440 return cmp(x, y) < 0; 00441 } 00442 00444 BigInt floor(const Real&, Real&); 00446 Real pow(const Real&, unsigned long); 00447 00449 inline int sign(const Real& r) { 00450 return r.sign(); 00451 } 00453 inline bool isZero(const Real& r) { 00454 return r.sign() == 0; 00455 } 00457 inline Real abs(const Real& x) { 00458 return x.abs(); 00459 } 00461 inline Real fabs(const Real& x) { 00462 return abs(x); 00463 } 00465 inline BigInt floor(const Real& r) { 00466 Real tmp; 00467 return floor(r, tmp); 00468 } 00470 inline BigInt ceil(const Real& r) { 00471 return -floor(-r); 00472 } 00474 inline Real power(const Real& r, unsigned long p) { 00475 return pow(r, p); 00476 } 00478 inline Real sqrt(const Real& x) { 00479 return x.sqrt(defAbsPrec); 00480 } 00481 00482 // class Realbase_for (need defined after Real) 00483 // unary minus operator 00484 template <class T> 00485 inline Real Realbase_for<T>::operator-() const { 00486 return -ker; 00487 } 00488 template <> 00489 inline Real RealLong::operator-() const { 00490 return ker < -LONG_MAX ? -BigInt(ker) : -ker; 00491 } 00492 00493 CORE_END_NAMESPACE 00494 #endif // _CORE_REAL_H_ 00495