mirror of https://github.com/CGAL/cgal
572 lines
16 KiB
C++
572 lines
16 KiB
C++
/******************************************************************
|
|
* Core Library Version 1.5, August 2002
|
|
* Copyright (c) 1995-2002 Exact Computation Project
|
|
*
|
|
* File: Real.h
|
|
*
|
|
* Synopsis: The Real class is a superclass for all the number
|
|
* systems in the Core Library (int, long, float, double,
|
|
* BigInt, BigRat, BigFloat, etc)
|
|
*
|
|
* Written by
|
|
* Koji Ouchi <ouchi@simulation.nyu.edu>
|
|
* Chee Yap <yap@cs.nyu.edu>
|
|
* Chen Li <chenli@cs.nyu.edu>
|
|
* Zilin Du <zilin@cs.nyu.edu>
|
|
* Sylvain Pion <pion@cs.nyu.edu>
|
|
*
|
|
* WWW URL: http://cs.nyu.edu/exact/
|
|
* Email: exact@cs.nyu.edu
|
|
*
|
|
* $Id$
|
|
*****************************************************************/
|
|
|
|
#ifndef CORE_REAL_H
|
|
#define CORE_REAL_H
|
|
|
|
#include "CoreImpl.h"
|
|
#include "CoreAux.h"
|
|
#include "BigFloat.h"
|
|
#include "MemoryPool.h"
|
|
|
|
CORE_BEGIN_NAMESPACE
|
|
|
|
// forward reference
|
|
class RealRep;
|
|
|
|
/**
|
|
* \class Real Real.h
|
|
* \brief Real is a superclass for all the number systems
|
|
*/
|
|
|
|
class Real
|
|
{
|
|
public:
|
|
/// \name Constructors and Destructor
|
|
//@{
|
|
/// default constructor
|
|
Real();
|
|
/// constructor for \c int
|
|
Real(int);
|
|
/// constructor for <tt>unsigned int</tt>
|
|
Real(unsigned int);
|
|
/// constructor for \c long
|
|
Real(long);
|
|
/// constructor for <tt>unsigned long</tt>
|
|
Real(unsigned long);
|
|
/// constructor for \c float
|
|
Real(float);
|
|
/// constructor for \c double
|
|
Real(double);
|
|
/// constructor for \c BigInt
|
|
Real(BigInt);
|
|
/// constructor for \c BigRat
|
|
Real(BigRat);
|
|
/// constructor for \c BigFloat
|
|
Real(BigFloat);
|
|
/// constructor for \c string
|
|
/** construct Real from a string representation \a s
|
|
* with precision \a prec */
|
|
Real(const char *str, const extLong& prec = defInputDigits);
|
|
/// copy constructor
|
|
Real(const Real&);
|
|
/// destructor
|
|
~Real();
|
|
//@}
|
|
|
|
/// \name Aprroximation Function
|
|
//@{
|
|
// approximation
|
|
Real approx(const extLong& relPrec = defRelPrec,
|
|
const extLong& absPrec = defAbsPrec) const;
|
|
//@}
|
|
|
|
/// \name Help Functions
|
|
//@{
|
|
/// get current approximate value
|
|
BigFloat getBigFloat() const;
|
|
/// get exponent of current approximate value
|
|
long getExponent() const;
|
|
/// get mantissa of current approximate value
|
|
BigInt getMantissa() const;
|
|
//@}
|
|
|
|
/// \name Conversion Functions
|
|
//@{
|
|
/// convert to \c int
|
|
int toInt() const ;
|
|
/// convert to \c long
|
|
long toLong() const ;
|
|
/// convert to \c float
|
|
float toFloat() const;
|
|
/// convert to \c double
|
|
double toDouble() const;
|
|
/// convert to \c string
|
|
/** give decimal string representation */
|
|
const char *toString() const;
|
|
/// convert to \c BigRat
|
|
BigRat toBigRat() const;
|
|
//@}
|
|
|
|
/// \name Assignment Operators
|
|
//@{
|
|
/// assignment operator
|
|
Real& operator=(const Real&);
|
|
/// += operator
|
|
Real& operator+=(const Real&);
|
|
/// -= operator
|
|
Real& operator-=(const Real&);
|
|
/// *= operator
|
|
Real& operator*=(const Real&);
|
|
/// /= operator
|
|
Real& operator/=(const Real&);
|
|
//@}
|
|
|
|
/// \name Increment, Decrement, and Unary Minus Operators
|
|
//@{
|
|
/// left increment operator (++i)
|
|
Real& operator++();
|
|
/// right increment operator (i++)
|
|
Real operator++(int);
|
|
/// left decrement operator (--i)
|
|
Real& operator--();
|
|
/// right deccrement operator (i--)
|
|
Real operator--(int);
|
|
/// unary minus
|
|
Real operator-() const;
|
|
//@}
|
|
|
|
/// \name Arithematic Operators
|
|
//@{
|
|
/// addition
|
|
friend Real operator+(const Real&, const Real&);
|
|
/// substraction
|
|
friend Real operator-(const Real&, const Real&);
|
|
/// multiplication
|
|
friend Real operator*(const Real&, const Real&);
|
|
/// division
|
|
friend Real operator/(const Real&, const Real&);
|
|
/// square root
|
|
friend Real sqrt(const Real&);
|
|
//@}
|
|
|
|
/// \name Comparison Operators
|
|
//@{
|
|
/// operator ==
|
|
friend bool operator==(const Real&, const Real&);
|
|
/// operator !=
|
|
friend bool operator!=(const Real&, const Real&);
|
|
/// operator <
|
|
friend bool operator< (const Real&, const Real&);
|
|
/// operator <=
|
|
friend bool operator<=(const Real&, const Real&);
|
|
/// operator <
|
|
friend bool operator> (const Real&, const Real&);
|
|
/// operator >=
|
|
friend bool operator>=(const Real&, const Real&);
|
|
//@}
|
|
|
|
/// \name Builtin Functions
|
|
//@{
|
|
/// sign function
|
|
friend int sign(const Real&);
|
|
/// isZero function
|
|
friend bool isZero(const Real&);
|
|
/// compare function
|
|
/** compare two Real \a e1 and \a e2, return
|
|
* \retval -1 if e1 < e2,
|
|
* \retval 0 if e1 = e2,
|
|
* \retval 1 if e1 > e2. */
|
|
friend int compare(const Real& e1, const Real& e2);
|
|
/// floor function
|
|
friend BigInt floor(const Real&);
|
|
/// ceil function
|
|
friend BigInt ceil(const Real&);
|
|
/// power function
|
|
friend Real pow(const Real&, unsigned long);
|
|
/// power function (same as pow())
|
|
friend Real power(const Real&, unsigned long n);
|
|
/// absolute value function
|
|
friend Real abs(const Real&);
|
|
/// absolute value function (same as abs())
|
|
friend Real fabs(const Real&);
|
|
//@}
|
|
|
|
/// \name I/O Stream
|
|
//@{
|
|
/// write to ostream
|
|
friend std::ostream& operator<<(std::ostream&, const Real&);
|
|
/// read from istream
|
|
friend std::istream& operator>>(std::istream&, Real&);
|
|
//@}
|
|
|
|
public:
|
|
/// \name Deprecated Functions
|
|
//@{
|
|
/// sign function
|
|
int sign() const;
|
|
/// return the pointer:
|
|
RealRep* get_rep() const { return rep; }
|
|
/// division with desired precision
|
|
Real div(const Real&, const extLong&) const;
|
|
/// squareroot
|
|
Real sqrt(const extLong&) const;
|
|
/// squareroot with initial approximation
|
|
Real sqrt(const extLong&, const BigFloat &) const;
|
|
|
|
/// return true if error free otherwise return false;
|
|
bool isExact() const;
|
|
/// low bound of MSB
|
|
extLong lMSB() const;
|
|
/// upper bound of MSB
|
|
extLong uMSB() const;
|
|
/// MSB - Most Significant Bit
|
|
extLong MSB() const;
|
|
|
|
/// correspond to the variables "u25, l25, v2p, v2m, v5p, v5m" in Expr
|
|
void ULV_E(extLong &up, extLong &lp, extLong &v2p, extLong &v2m,
|
|
extLong &v5p, extLong &v5m) const;
|
|
/// floor of log_2 of Error
|
|
extLong flrLgErr() const;
|
|
/// ceil of log_2 of Error
|
|
extLong clLgErr() const;
|
|
/// return true if interval contains zero
|
|
bool isZeroIn() const;
|
|
/// degree of polynomial P(x)
|
|
unsigned long degree() const;
|
|
/// || P(X) ||_2
|
|
unsigned long length() const;
|
|
/// || P(X) ||_\infty
|
|
unsigned long height() const;
|
|
//@}
|
|
/// return Real(0)
|
|
static const Real& getZero();
|
|
|
|
protected:
|
|
RealRep* rep; ///< handle to the "real" representation
|
|
};//Class Real
|
|
|
|
|
|
template <class T>
|
|
class Realbase_for;
|
|
|
|
typedef Realbase_for<long> RealLong;
|
|
typedef Realbase_for<double> RealDouble;
|
|
typedef Realbase_for<BigInt> RealBigInt;
|
|
typedef Realbase_for<BigRat> RealBigRat;
|
|
typedef Realbase_for<BigFloat> RealBigFloat;
|
|
|
|
|
|
|
|
/// \class RealRep
|
|
/// \brief The internal representation of Real
|
|
class RealRep
|
|
{
|
|
public:
|
|
/// reference counter
|
|
unsigned refCount;
|
|
|
|
/// most Significant Bit
|
|
/** DEFINITION: MSB(0)=-\infty. When E is not 0, and real, we define MSB(E)
|
|
to be the natural number m such that 2^{m} <= |E| < 2^{m+1}. Hence,
|
|
MSB(E) is equal to floor(log_2(|E|)). Intuitively, MSB is the position
|
|
of the most significant bit in a binary rational representation of |E|.
|
|
Thus, the bit before the binary point is considered to be position 0,
|
|
the the bit after the binary point is position -1. Thus,
|
|
... b_2 b_1 b_0.b_{-1} b_{-2} ...
|
|
E.g., MSB(1) = 0,
|
|
MSB(1/2) = MSB((0.1)_2) = -1
|
|
MSB(1/4) = MSB((0.01)_2) = -2.
|
|
MSB(2) = MSB(3) = 1, MSB(4) = 2.
|
|
Hence, if E is a non-zero integer, MSB(E) is equal to bitlength(|E|)-1.
|
|
We also need upper and lower bounds on MSB(E). This is defined to be
|
|
any numbers lMSB(E) and uMSB(E) such that lMSB(E) <= MSB(E) <= uMSB(E).
|
|
THIS implies the following inequality:
|
|
2^{lMSB(E)} <= |E| < 2^{1+uMSB(E)}.
|
|
When E is an interval (e.g., BigFloat with non-zero error), then MSB(E)
|
|
is not defined, but uMSB(E) and lMSB(E) is defined as follows:
|
|
Assume E = [a, b].
|
|
If 0 < a <= b, then lMSB(E) <= MSB(a) <= MSB(b) <= uMSB(E)
|
|
If a <= b < 0, then lMSB(E) <= MSB(b) <= MSB(a) <= uMSB(E)
|
|
If a <= 0 <= b, then lMSB(E) = MSB(0) = -\infty
|
|
uMSB(E) >= max( MSB(a), MSB(b) ) */
|
|
extLong mostSignificantBit;
|
|
|
|
/// \name Constructor and Destructor
|
|
//@{
|
|
/// Constructor
|
|
RealRep() : refCount(1) {}
|
|
/// Destructor
|
|
virtual ~RealRep() {}
|
|
//@}
|
|
|
|
/// \name Cast Operators
|
|
//@{
|
|
virtual operator double() const = 0;
|
|
virtual operator float() const = 0;
|
|
virtual operator long() const = 0;
|
|
virtual operator int() const = 0;
|
|
virtual BigFloat getBigFloat() const = 0;
|
|
virtual BigRat toBigRat() const = 0;
|
|
//@}
|
|
|
|
/// \name Approximation
|
|
//@{
|
|
virtual Real approx(const extLong&, const extLong&) const = 0;
|
|
//@}
|
|
|
|
/// \name unary minus
|
|
//@{
|
|
virtual Real operator -() const = 0;
|
|
//@}
|
|
|
|
/// \name addition
|
|
//@{
|
|
virtual Real operator +(const Real&) const = 0;
|
|
virtual Real addLong(const RealLong&) const = 0;
|
|
virtual Real addDouble(const RealDouble&) const = 0;
|
|
virtual Real addBigInt(const RealBigInt&) const = 0;
|
|
virtual Real addBigFloat(const RealBigFloat&) const = 0;
|
|
virtual Real addBigRat(const RealBigRat&) const = 0;
|
|
//@}
|
|
|
|
/// \name subtraction
|
|
//@{
|
|
virtual Real operator -(const Real&) const = 0;
|
|
virtual Real subLong(const RealLong&) const = 0;
|
|
virtual Real subDouble(const RealDouble&) const = 0;
|
|
virtual Real subBigInt(const RealBigInt&) const = 0;
|
|
virtual Real subBigFloat(const RealBigFloat&) const = 0;
|
|
virtual Real subBigRat(const RealBigRat&) const = 0;
|
|
//@}
|
|
|
|
/// \name multiplication
|
|
//@{
|
|
virtual Real operator *(const Real&) const = 0;
|
|
virtual Real mulLong(const RealLong&) const = 0;
|
|
virtual Real mulDouble(const RealDouble&) const = 0;
|
|
virtual Real mulBigInt(const RealBigInt&) const = 0;
|
|
virtual Real mulBigFloat(const RealBigFloat&) const = 0;
|
|
virtual Real mulBigRat(const RealBigRat&) const = 0;
|
|
//@}
|
|
|
|
/// \name division
|
|
//@{
|
|
// virtual Real operator /(const Real&) const;
|
|
virtual Real div(const Real&, const extLong&) const = 0;
|
|
virtual Real divLong(const RealLong&, const extLong&) const = 0;
|
|
virtual Real divDouble(const RealDouble&, const extLong&) const = 0;
|
|
virtual Real divBigInt(const RealBigInt&, const extLong&) const = 0;
|
|
virtual Real divBigFloat(const RealBigFloat&, const extLong&) const = 0;
|
|
virtual Real divBigRat(const RealBigRat&, const extLong&) const = 0;
|
|
//@}
|
|
|
|
/// \name squareroot
|
|
//@{
|
|
virtual Real sqrt(const extLong&) const = 0;
|
|
// sqrt with initial approximation
|
|
virtual Real sqrt(const extLong&, const BigFloat &) const = 0;
|
|
//@}
|
|
|
|
/// \name equality
|
|
//@{
|
|
virtual bool operator ==(const Real&) const = 0;
|
|
virtual bool eqlLong(const RealLong&) const = 0;
|
|
virtual bool eqlDouble(const RealDouble&) const = 0;
|
|
virtual bool eqlBigInt(const RealBigInt&) const = 0;
|
|
virtual bool eqlBigFloat(const RealBigFloat&) const = 0;
|
|
virtual bool eqlBigRat(const RealBigRat&) const = 0;
|
|
//@}
|
|
|
|
/// \name smaller than
|
|
//@{
|
|
virtual bool operator <(const Real&) const = 0;
|
|
virtual bool grtLong(const RealLong&) const = 0;
|
|
virtual bool grtDouble(const RealDouble&) const = 0;
|
|
virtual bool grtBigInt(const RealBigInt&) const = 0;
|
|
virtual bool grtBigFloat(const RealBigFloat&) const = 0;
|
|
virtual bool grtBigRat(const RealBigRat&) const = 0;
|
|
//@}
|
|
|
|
// builtin functions
|
|
//@{
|
|
virtual bool isExact() const = 0;
|
|
virtual void ULV_E(extLong &up, extLong &lp, extLong &v2p, extLong &v2m,
|
|
extLong &v5p, extLong &v5m) const = 0;
|
|
virtual extLong flrLgErr() const = 0;
|
|
virtual extLong clLgErr() const = 0;
|
|
virtual bool isZeroIn() const = 0;
|
|
virtual unsigned long degree() const = 0;
|
|
virtual unsigned long length() const = 0;
|
|
virtual unsigned long height() const = 0;
|
|
virtual int sgn() const = 0;
|
|
//@}
|
|
// I/O Stream
|
|
//@{
|
|
virtual std::ostream& operator <<(std::ostream&) const = 0;
|
|
//@}
|
|
}; //class RealRep
|
|
|
|
|
|
template <class T>
|
|
class Realbase_for : public RealRep
|
|
{
|
|
public:
|
|
CORE_MEMORY(Realbase_for)
|
|
|
|
/// Kernel
|
|
T ker;
|
|
|
|
/// \name Constructor and Destructor
|
|
//@{
|
|
/// Constructor
|
|
Realbase_for(const T&);
|
|
/// Destructor
|
|
~Realbase_for() {}
|
|
//@}
|
|
|
|
/// Access to ker
|
|
const T& get_ker() const { return ker; }
|
|
|
|
/// \name cast operators
|
|
//@{
|
|
operator double() const;
|
|
operator float() const;
|
|
operator long() const;
|
|
operator int() const;
|
|
BigFloat getBigFloat() const;
|
|
BigRat toBigRat() const;
|
|
//@}
|
|
|
|
/// \name approximation
|
|
//@{
|
|
Real approx(const extLong&, const extLong&) const;
|
|
//@}
|
|
|
|
/// \name unary minus
|
|
//@{
|
|
Real operator -() const;
|
|
//@}
|
|
|
|
/// \name addition
|
|
//@{
|
|
Real operator +(const Real&) const;
|
|
Real addLong(const RealLong&) const;
|
|
Real addDouble(const RealDouble&) const;
|
|
Real addBigInt(const RealBigInt&) const;
|
|
Real addBigFloat(const RealBigFloat&) const;
|
|
Real addBigRat(const RealBigRat&) const;
|
|
//@}
|
|
|
|
/// \name subtraction
|
|
//@{
|
|
Real operator -(const Real&) const;
|
|
Real subLong(const RealLong&) const;
|
|
Real subDouble(const RealDouble&) const;
|
|
Real subBigInt(const RealBigInt&) const;
|
|
Real subBigFloat(const RealBigFloat&) const;
|
|
Real subBigRat(const RealBigRat&) const;
|
|
//@}
|
|
|
|
/// \name multiplication
|
|
//@{
|
|
Real operator *(const Real&) const;
|
|
Real mulLong(const RealLong&) const;
|
|
Real mulDouble(const RealDouble&) const;
|
|
Real mulBigInt(const RealBigInt&) const;
|
|
Real mulBigFloat(const RealBigFloat&) const;
|
|
Real mulBigRat(const RealBigRat&) const;
|
|
//@}
|
|
|
|
/// \name division
|
|
//@{
|
|
Real div(const Real&, const extLong&) const;
|
|
Real divLong(const RealLong&, const extLong&) const;
|
|
Real divDouble(const RealDouble&, const extLong&) const;
|
|
Real divBigInt(const RealBigInt&, const extLong&) const;
|
|
Real divBigFloat(const RealBigFloat&, const extLong&) const;
|
|
Real divBigRat(const RealBigRat&, const extLong&) const;
|
|
//@}
|
|
|
|
/// \name squareroot
|
|
//@{
|
|
Real sqrt(const extLong&) const;
|
|
Real sqrt(const extLong&, const BigFloat&) const;
|
|
//@}
|
|
|
|
/// \name equality
|
|
//@{
|
|
bool operator ==(const Real&) const;
|
|
bool eqlLong(const RealLong&) const;
|
|
bool eqlDouble(const RealDouble&) const;
|
|
bool eqlBigInt(const RealBigInt&) const;
|
|
bool eqlBigFloat(const RealBigFloat&) const;
|
|
bool eqlBigRat(const RealBigRat&) const;
|
|
//@}
|
|
|
|
/// \name smaller-than
|
|
//@{
|
|
bool operator <(const Real&) const;
|
|
bool grtLong(const RealLong&) const;
|
|
bool grtDouble(const RealDouble&) const;
|
|
bool grtBigInt(const RealBigInt&) const;
|
|
bool grtBigFloat(const RealBigFloat&) const;
|
|
bool grtBigRat(const RealBigRat&) const;
|
|
//@}
|
|
|
|
/// \name builtin functions
|
|
//@{
|
|
bool isExact() const;
|
|
void ULV_E(extLong &up, extLong &lp, extLong &v2p, extLong &v2m,
|
|
extLong &v5p, extLong &v5m) const;
|
|
extLong flrLgErr() const;
|
|
extLong clLgErr() const;
|
|
bool isZeroIn() const;
|
|
unsigned long degree() const;
|
|
unsigned long length() const;
|
|
unsigned long height() const;
|
|
int sgn() const;
|
|
//@}
|
|
|
|
/// \name I/O stream
|
|
//@{
|
|
std::ostream& operator <<(std::ostream&) const;
|
|
//@}
|
|
};
|
|
|
|
BigInt floor(const Real&, Real&);
|
|
Real pow(const Real&, unsigned long);
|
|
#ifdef CORE_ENABLE_INLINES
|
|
#include "Real.inl"
|
|
#else
|
|
// friend functions for Real class
|
|
// (need declarations in case they are not inlined)
|
|
Real operator+(const Real&, const Real&);
|
|
Real operator-(const Real&, const Real&);
|
|
Real operator*(const Real&, const Real&);
|
|
Real operator/(const Real&, const Real&);
|
|
Real sqrt(const Real&);
|
|
bool operator==(const Real&, const Real&);
|
|
bool operator!=(const Real&, const Real&);
|
|
bool operator< (const Real&, const Real&);
|
|
bool operator<=(const Real&, const Real&);
|
|
bool operator> (const Real&, const Real&);
|
|
bool operator>=(const Real&, const Real&);
|
|
int sign(const Real&);
|
|
bool isZero(const Real&);
|
|
int compare(const Real& e1, const Real& e2);
|
|
BigInt floor(const Real&);
|
|
BigInt ceil(const Real&);
|
|
Real power(const Real&, unsigned long n);
|
|
Real abs(const Real&);
|
|
Real fabs(const Real&);
|
|
std::ostream& operator<<(std::ostream&, const Real&);
|
|
std::istream& operator>>(std::istream&, Real&);
|
|
#endif
|
|
|
|
#define CORE_REAL_ZERO Real::getZero()
|
|
|
|
CORE_END_NAMESPACE
|
|
|
|
#endif
|