BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/CORE/Real.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: 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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines