cgal/Packages/Core/include/CORE/BigFloatRep.h

179 lines
5.4 KiB
C++

/******************************************************************
* Core Library Version 1.6, June 2003
* Copyright (c) 1995-2003 Exact Computation Project
*
* File: BigFloatRep.h
*
* Synopsis: Internal Representation BigFloat.
*
* Written by
* Chee Yap <yap@cs.nyu.edu>
* Zilin Du <zilin@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $Id$
*****************************************************************/
#ifndef CORE_BIGFLOATREP_H
#define CORE_BIGFLOATREP_H
#ifdef DEBUG
#include <assert.h>
#endif
#include <CORE/CoreImpl.h>
#include <CORE/CoreAux.h>
#include <CORE/CoreDefs.h>
#include <CORE/extLong.h>
#include <CORE/BigInt.h>
#include <CORE/BigRat.h>
#include <CORE/MemoryPool.h>
CORE_BEGIN_NAMESPACE
// forward reference
class BigFloat;
// class BigFloatRep (internal representation for BigFloat)
class BigFloatRep
{
private:
static long chunkCeil(long bits); //inline
static long chunkFloor(long bits); //inline
static long bits(long chunks); //inline
static BigInt chunkShift(const BigInt& x, long s); //inline
static double lg10(BigInt x); //inline
static long floorlg10(BigInt x); //inline
static void error(const char*); //inline
/// exp2(e) returns 2^e : called by BigFloat::exp2(e)
/** e can be negative */
static BigFloatRep* exp2(int e);
struct DecimalOutput;
friend class BigFloat;
BigInt m;
unsigned long err;
long exp;
unsigned refCount;
public:
// constructors
BigFloatRep(double);
CORE_INLINE BigFloatRep(const BigInt& I = 0, unsigned long u = 0, long l = 0);
CORE_INLINE BigFloatRep(const char *);
CORE_INLINE BigRat BigRatize() const;
// the destructor
CORE_INLINE ~BigFloatRep();
CORE_MEMORY(BigFloatRep)
// approximation
void trunc(const BigInt&, const extLong&, const extLong&);
void truncM(const BigFloatRep&, const extLong&, const extLong&);
void approx(const BigFloatRep&, const extLong&, const extLong&);
void div(const BigInt&, const BigInt&, const extLong&, const extLong&);
void approx(const BigRat&, const extLong&, const extLong&); //inline
// error-normalization
void eliminateTrailingZeroes(); //inline
void normal();
void bigNormal(BigInt&);
// arithmetics
public:
void add(const BigFloatRep&, const BigFloatRep&);
void sub(const BigFloatRep&, const BigFloatRep&);
void mul(const BigFloatRep&, const BigFloatRep&);
void div(const BigFloatRep&, const BigFloatRep&, const extLong&);
void div2(const BigFloatRep&); // exact division by 2
void centerize(const BigFloatRep&, const BigFloatRep&);
private:
// squareroot
// arguments: r = value whose square root we want
// a = absolute precision of the desired result
// init = initial approx. to the square root (for Newton)
void sqrt(const BigInt& r, const extLong& a);
void sqrt(const BigInt& r, const extLong& a, const BigFloat& init);
void sqrt(const BigFloatRep& r, const extLong& a);
void sqrt(const BigFloatRep& r, const extLong& a, const BigFloat& init);
// comparison
int compareMExp(const BigFloatRep&) const;
// builtin functions
CORE_INLINE extLong lMSB() const; //inline
CORE_INLINE extLong uMSB() const; //inline
CORE_INLINE extLong MSB() const; //inline
CORE_INLINE extLong flrLgErr() const; //inline
CORE_INLINE extLong clLgErr() const; //inline
CORE_INLINE bool isZeroIn() const; //inline
CORE_INLINE int signM() const; //inline
// cast functions
double toDouble() const;
long toLong() const;
BigInt toBigInt() const;
// conversion
// toString() Joaquin Grech 31/5/2003
std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const;
std::string round(std::string inRep, unsigned int width) const;
DecimalOutput toDecimal(unsigned int width=defBigFloatOutputDigits,
bool Scientific=false) const;
void fromString(const char *p, const extLong & prec = defBigFloatInputDigits);
void dump() const; //inline
long adjustE(long E, BigInt M, long e) const;
public:
// stream operators
std::ostream& operator <<(std::ostream&) const; //inline
std::istream& operator >>(std::istream&);
};
struct BigFloatRep::DecimalOutput {
std::string rep; // decimal output string
int sign; // 0, +1 or -1
bool isScientific; // false=positional notation
int noSignificant; // number of significant digits
// -1 means this information is not explicitly
// given, and must be determined from rep, etc.
bool isExact; //
int errorCode; // 0 = no error
// 1 = sign of number is unknown (e.g., mantissa
// is smaller than error)
DecimalOutput() : rep(""), sign(1), isScientific(false),
noSignificant(0), isExact(false), errorCode(0)
{}
};
// constants used by BigFloatRep
// NOTES: CHUNK_BIT is the number of bits in each Chunk
// Since LONG_BIT = 32 or 64, then CHUNK_BIT = 14 or 30.
// We have: 0 <= err < 4 * 2^{CHUNK_BIT}
const long CHUNK_BIT = (long)(LONG_BIT / 2 - 2); // chunks
const long HALF_CHUNK_BIT = (CHUNK_BIT + 1) / 2;
const long DBL_MAX_CHUNK = (DBL_MAX_EXP - 1) / CHUNK_BIT + 1;
const double lgTenM = 3.321928094887362;
#ifdef CORE_ENABLE_INLINES
#include <CORE/BigFloat.inl>
#endif
CORE_END_NAMESPACE
#endif