Header-only CGAL_Core

This commit is contained in:
Clement Jamin 2014-12-15 21:34:29 +01:00
parent 3915c89c17
commit 93a007616a
29 changed files with 4006 additions and 3892 deletions

View File

@ -37,6 +37,13 @@
#include <CGAL/CORE/BigFloatRep.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
class Expr;
@ -83,8 +90,8 @@ public:
BigFloat(const BigInt& I)
: RCBigFloat(new BigFloatRep(I)) {}
/// constructor for <tt>BigRat</tt>
BigFloat(const BigRat& R, const extLong& r = defRelPrec,
const extLong& a = defAbsPrec)
BigFloat(const BigRat& R, const extLong& r = get_static_defRelPrec(),
const extLong& a = get_static_defAbsPrec())
: RCBigFloat(new BigFloatRep()) {
rep->approx(R, r, a);
}
@ -93,8 +100,8 @@ public:
// know about Expr, but BigFloat has a special role in our system!
// ===============================
/// constructor for <tt>Expr</tt>
explicit BigFloat(const Expr& E, const extLong& r = defRelPrec,
const extLong& a = defAbsPrec);
explicit BigFloat(const Expr& E, const extLong& r = get_static_defRelPrec(),
const extLong& a = get_static_defAbsPrec());
//Dummy
explicit BigFloat(const BigFloat& E, const extLong& ,
@ -161,7 +168,7 @@ public:
/// operator/=
BigFloat& operator/= (const BigFloat& x) {
BigFloat z;
z.rep->div(*rep, *x.rep, defBFdivRelPrec);
z.rep->div(*rep, *x.rep, get_static_defBFdivRelPrec());
*this = z;
return *this;
}
@ -182,11 +189,11 @@ public:
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt> (base = 10)
void fromString(const char* s, const extLong& p=defBigFloatInputDigits) {
void fromString(const char* s, const extLong& p=get_static_defBigFloatInputDigits()) {
rep->fromString(s, p);
}
/// convert to <tt>std::string</tt> (base = 10)
std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const {
std::string toString(long prec=get_static_defBigFloatOutputDigits(), bool sci=false) const {
return rep->toString(prec, sci);
}
std::string str() const {
@ -435,7 +442,7 @@ inline BigFloat operator* (const BigFloat& x, const BigFloat& y) {
/// operator/
inline BigFloat operator/ (const BigFloat& x, const BigFloat& y) {
BigFloat z;
z.getRep().div(x.getRep(),y.getRep(),defBFdivRelPrec);
z.getRep().div(x.getRep(),y.getRep(),get_static_defBFdivRelPrec());
return z;
}
@ -490,12 +497,12 @@ inline BigFloat power(const BigFloat& x, unsigned long p) {
/// The argument x is an initial approximation.
BigFloat root(const BigFloat&, unsigned long k, const extLong&, const BigFloat&);
inline BigFloat root(const BigFloat& x, unsigned long k) {
return root(x, k, defBFsqrtAbsPrec, x);
return root(x, k, get_static_defBFsqrtAbsPrec(), x);
}
/// sqrt to defAbsPrec:
inline BigFloat sqrt(const BigFloat& x) {
return x.sqrt(defBFsqrtAbsPrec);
return x.sqrt(get_static_defBFsqrtAbsPrec());
}
/// convert an BigFloat Interval to a BigFloat with error bits
@ -625,4 +632,10 @@ inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){
*this = f.BigRatValue();
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/BigFloat_impl.h>
#include <CGAL/CORE/CoreIO_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_BIGFLOAT_H_

View File

@ -40,6 +40,13 @@
#include <CGAL/CORE/CoreDefs.h>
#include <CGAL/CORE/extLong.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
// forward reference
@ -144,11 +151,11 @@ private:
// conversion
// toString() Joaquin Grech 31/5/2003
std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const;
std::string toString(long prec=get_static_defBigFloatOutputDigits(), bool sci=false) const;
std::string round(std::string inRep, long& L10, unsigned int width) const;
DecimalOutput toDecimal(unsigned int width=defBigFloatOutputDigits,
DecimalOutput toDecimal(unsigned int width=get_static_defBigFloatOutputDigits(),
bool Scientific=false) const;
void fromString(const char *p, const extLong & prec = defBigFloatInputDigits);
void fromString(const char *p, const extLong & prec = get_static_defBigFloatInputDigits());
void dump() const; //inline
long adjustE(long E, BigInt M, long e) const;

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,13 @@
#include <CGAL/CORE/MemoryPool.h>
#include <string>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
@ -559,4 +566,9 @@ inline BigInt randomize(const BigInt& a) {
//@}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
//#include <CGAL/CORE/CoreIO_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_BIGINT_H_

View File

@ -39,6 +39,13 @@
#include <fstream>
#include "CGAL/CORE/Impl.h"
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
#ifndef LONG_BIT // such as in Linux
@ -181,4 +188,9 @@ inline void core_debug(std::string msg){
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/CoreAux_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_COREAUX_H_

View File

@ -0,0 +1,229 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: CoreAux.cpp
* Synopsis:
* Auxiliary routines such as ceiling of log_2, etc.
* they are not specific to any Core classes.
*
* Written by
* Chee Yap <yap@cs.nyu.edu>
* Chen Li <chenli@cs.nyu.edu>
* Zilin Du <zilin@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/CORE/CoreAux.h>
#include <gmp.h>
namespace CORE {
////////////////////////////////////////////////////////////
// More useful functions to implement:
//
// To convert digits into bits:
// given X, compute X * log_2(10)
// To convert bits into digits:
// given X, compute X * log_10(2)
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// flrLg(x)
// returns floor log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int flrLg(long x) {
if (x == LONG_MIN) {
// special treatment as -LONG_MIN would be not representable as "long"
return LONG_BIT - 1;
} else {
// 1 <= |x| <= LONG_MAX
if (x < 0)
x = - x;
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
}
////////////////////////////////////////////////////////////
// floor log base 2 of unsigned long x
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int flrLg(unsigned long x) {
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int clLg(long x) {
if (x == LONG_MIN)
return LONG_BIT - 1;
if (x < 0)
x = -x; // use absolute value
if (x > (LONG_MAX >> 1)) // the leading data bit is 1
return (LONG_BIT - 1); // exclude the sign bit
if (x >= 2)
return flrLg((unsigned long)((x << 1) - 1));
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2
if (x == 1)
return 0;
return -1; // x must be 0 here
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of unsigned long x
// CONVENTION lg(0) = -1
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int clLg(unsigned long x) {
if (x > (ULONG_MAX >> 1)) // the leading bit is 1
return LONG_BIT;
if (x >= 2)
return flrLg((x << 1) - 1);
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2.
if (x == 1)
return 0;
return -1; // x must be equal to 0
}
/// gcd for machine type long
/** This is needed when we construct Polynomials with int or long coefficients */
CGAL_INLINE_FUNCTION
long gcd(long m, long n) {
if (m == 0)
return core_abs(n);
if (n == 0)
return core_abs(m);
long p = core_abs(m);
long q = core_abs(n);
if (p<q)
core_swap(p, q);
while (q>0) {
long r = p % q;
p = q;
q = r;
}
return p;
}
// return a gmp_randstate_t structure
CGAL_INLINE_FUNCTION
gmp_randstate_t* getRandstate() {
static gmp_randstate_t rstate;
static bool initialized = false;
if (!initialized) {
gmp_randinit(rstate, GMP_RAND_ALG_DEFAULT, 32L);
initialized = true;
}
return &rstate;
}
// char* core_itoa(int n, char* buffer)
// returns a pointer to the null-terminated string in buffer
// NOTES:
// 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit
// (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes.
// 1. itoa(...) is available on some stdlib.h, but it is
// not defined by ANSI-C and so not all compilers support it.
// 2. Our use of sprintf(...) to do the job is known to
// be inefficient, but this is hardly critical for our usage.
// 3. A more general program should take a 3rd argument (the radix of
// output number). We assume radix 10.
CGAL_INLINE_FUNCTION
char * core_itoa(int n, char* buffer) {
std::sprintf(buffer, "%d", n);
return buffer;
}
/// implements the "integer mantissa" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
CGAL_INLINE_FUNCTION
double IntMantissa(double d) {
int e;
return std::ldexp(std::frexp(d, &e), 53);
}
/// implements the "integer exponent" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
CGAL_INLINE_FUNCTION
int IntExponent(double d) {
int e;
std::frexp(d, &e);
return e-53;
}
/// CORE_DIAGFILE is file name for core_error(..) output.
const char* CORE_DIAGFILE = "Core_Diagnostics"; // global file name
/// core_error is the method to write Core Library warning or error messages
/** Both warnings and errors are written to a file called CORE_DIAGFILE.
* But errors are also written on std:cerr (similar to std::perror()).
* */
// Usage: core_error(message, file_with_error, line_number, err_type)
// where err_type=0 means WARNING, error_type=0 means ERROR
CGAL_INLINE_FUNCTION
void core_error(std::string msg, std::string file, int lineno, bool err) {
std::ofstream outFile(CORE_DIAGFILE, std::ios::app); // open to append
if (!outFile) {
// perror("CORE ERROR: cannot open Core Diagnostics file");
std::cerr << "CORE ERROR: can't open Core Diagnostics file"<<std::endl;
std::exit(1); //Note: do not call abort()
}
outFile << "CORE " << (err? "ERROR" : "WARNING")
<< " (at " << file << ": " << lineno << "): "
<< msg << std::endl;
outFile.close();
if (err) {
char buf[65];
// perror((std::string("CORE ERROR") + " (file " + file + ", line "
// + core_itoa(lineno,buf) +"):" + msg + "\n").c_str());
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
+ core_itoa(lineno,buf) +"):" + msg + "\n").c_str();
std::exit(1); //Note: do not call abort()
}
}
} //namespace CORE

View File

@ -40,6 +40,33 @@
#include <CGAL/CORE/extLong.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
#ifdef CGAL_HEADER_ONLY
#define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \
inline TYPE & get_static_##NAME() \
{ \
static TYPE NAME = VALUE; \
return NAME; \
}
#else // CGAL_HEADER_ONLY
#define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \
CGAL_EXPORT extern TYPE NAME; \
inline TYPE& get_static_##NAME() \
{ \
return NAME; \
}
#endif // CGAL_HEADER_ONLY
namespace CORE {
//////////////////////////////////////////////////////////////
@ -60,34 +87,34 @@ namespace CORE {
/** The normal behavior is to abort when an invalid expression
* is constructed. This flag can be used to turn off this abort.
* In any case, an error message will be printed */
CGAL_CORE_EXPORT extern bool AbortFlag;
CGAL_GLOBAL_STATE_VAR(bool, AbortFlag, true)
/// Invalid Flag -- initiallly value is non-negative
/** If the Abort Flag is false, then the Invalid flag will be set to
* a negative value whenever an invalid expression is constructed.
* It is the user's responsibility to check this flag and to make
* it non-negative again. */
CGAL_CORE_EXPORT extern int InvalidFlag;
CGAL_GLOBAL_STATE_VAR(int, InvalidFlag, 0)
/// Escape Precision in bits
CGAL_CORE_EXPORT extern extLong EscapePrec;
CGAL_GLOBAL_STATE_VAR(extLong, EscapePrec, CORE_posInfty)
/// current ur when EscapePrec triggered
/** this flag becomes negative when default EscapePrec is applied */
CGAL_CORE_EXPORT extern long EscapePrecFlag;
CGAL_GLOBAL_STATE_VAR(long, EscapePrecFlag, 0)
/// Escape Precision Warning Flag
/** this flag is true by default, and will cause a warning to be printed
when EscapePrec is reached */
CGAL_CORE_EXPORT extern bool EscapePrecWarning;
CGAL_GLOBAL_STATE_VAR(bool, EscapePrecWarning, true)
// These following two values determine the precision of computing
// approximations in Expr.
/// default Relative Precision in bits
CGAL_CORE_EXPORT extern extLong defRelPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defRelPrec, 60)
/// default Absolute Precision in bits
CGAL_CORE_EXPORT extern extLong defAbsPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defAbsPrec, CORE_posInfty)
/// default # of decimal digits for conversion from a BF to string.
/** This value cannot be CORE_INFTY.
@ -97,42 +124,41 @@ CGAL_CORE_EXPORT extern extLong defAbsPrec;
"controls the printout precision of std::cout for BigFloat"
Perhaps, we should merge defOutputDigits and defBigFloatOutputDigits?
*/
CGAL_CORE_EXPORT extern long defBigFloatOutputDigits;
CGAL_GLOBAL_STATE_VAR(long, defBigFloatOutputDigits, 10)
/// default input precision in digits for converting a string to a Real or Expr
/** This value can be CORE_INFTY */
CGAL_CORE_EXPORT extern extLong defInputDigits;
CGAL_GLOBAL_STATE_VAR(extLong, defInputDigits, CORE_posInfty)
/// controls the printout precision of std::cout for Real and Expr
/** This value cannot be CORE_INFTY
See also defBigFloatOutputDigits.
(it really should be an int, as in std::cout.setprecision(int)). */
CGAL_CORE_EXPORT extern long defOutputDigits;
CGAL_GLOBAL_STATE_VAR(long, defOutputDigits, get_static_defBigFloatOutputDigits())
/// default input precision in digits for converting a string to a BigFloat
/** This value cannot be CORE_INFTY. */
CGAL_CORE_EXPORT extern long defBigFloatInputDigits;
CGAL_GLOBAL_STATE_VAR(long, defBigFloatInputDigits, 16)
/// default BigFloat Division Relative Precision
CGAL_CORE_EXPORT extern extLong defBFdivRelPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defBFdivRelPrec, 54)
/// default BigFloat Sqrt Absolute Precision
CGAL_CORE_EXPORT extern extLong defBFsqrtAbsPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defBFsqrtAbsPrec, 54)
//////////////////////////////////////////////////////////////
// Mode parameters: incremental, progressive, filters
//////////////////////////////////////////////////////////////
/// floating point filter flag
CGAL_CORE_EXPORT extern bool fpFilterFlag;
CGAL_GLOBAL_STATE_VAR(bool, fpFilterFlag, true)
/// if true, evaluation of expressions would be incremental
CGAL_CORE_EXPORT extern bool incrementalEvalFlag;
CGAL_GLOBAL_STATE_VAR(bool, incrementalEvalFlag, true)
/// progressive evaluation flag
CGAL_CORE_EXPORT extern bool progressiveEvalFlag;
CGAL_GLOBAL_STATE_VAR(bool, progressiveEvalFlag, true)
/// rational reduction flag
CGAL_CORE_EXPORT extern bool rationalReduceFlag;
CGAL_GLOBAL_STATE_VAR(bool, rationalReduceFlag, false)
/// default initial (bit) precision for AddSub Progressive Evaluation
CGAL_CORE_EXPORT extern long defInitialProgressivePrec;
CGAL_GLOBAL_STATE_VAR(long, defInitialProgressivePrec, 64)
//////////////////////////////////////////////////////////////
// methods for setting global precision parameters
@ -144,87 +170,87 @@ CGAL_CORE_EXPORT extern long defInitialProgressivePrec;
/** It determines the precision to which an Expr evaluates its
(exact, implicit) constant value. */
inline void setDefaultPrecision(const extLong &r, const extLong &a) {
defRelPrec = r;
defAbsPrec = a;
get_static_defRelPrec() = r;
get_static_defAbsPrec() = a;
}
/// set default relative precision
inline extLong setDefaultRelPrecision(const extLong &r) {
extLong old = defRelPrec;
defRelPrec = r;
extLong old = get_static_defRelPrec();
get_static_defRelPrec() = r;
return old;
}
/// set default absolute precision
inline extLong setDefaultAbsPrecision(const extLong &a) {
extLong old = defAbsPrec;
defAbsPrec = a;
extLong old = get_static_defAbsPrec();
get_static_defAbsPrec() = a;
return old;
}
/// set default input digits (for Expr, Real)
/** it controls the absolute error */
inline extLong setDefaultInputDigits(const extLong &d) {
extLong old = defInputDigits;
defInputDigits = d;
extLong old = get_static_defInputDigits();
get_static_defInputDigits() = d;
return old;
}
/// set default output digits (for Expr, Real)
inline long setDefaultOutputDigits(long d = defOutputDigits,
inline long setDefaultOutputDigits(long d = get_static_defOutputDigits(),
std::ostream& o = std::cout) {
long old = defOutputDigits;
defOutputDigits = d;
long old = get_static_defOutputDigits();
get_static_defOutputDigits() = d;
o.precision(d);
return old;
}
/// set default input digits for BigFloat
inline long setDefaultBFInputDigits(long d) {
long old = defBigFloatInputDigits;
defBigFloatInputDigits = d;
long old = get_static_defBigFloatInputDigits();
get_static_defBigFloatInputDigits() = d;
return old;
}
/// set default output digits for BigFloat
inline long setDefaultBFOutputDigits(long d) {
long old = defBigFloatOutputDigits;
defBigFloatOutputDigits = d;
long old = get_static_defBigFloatOutputDigits();
get_static_defBigFloatOutputDigits() = d;
return old;
}
/// turn floating-point filter on/off
inline bool setFpFilterFlag(bool f) {
bool oldf = fpFilterFlag;
fpFilterFlag = f;
bool oldf = get_static_fpFilterFlag();
get_static_fpFilterFlag() = f;
return oldf;
}
/// turn incremental evaluation flag on/off
inline bool setIncrementalEvalFlag(bool f) {
bool oldf = incrementalEvalFlag;
incrementalEvalFlag = f;
bool oldf = get_static_incrementalEvalFlag();
get_static_incrementalEvalFlag() = f;
return oldf;
}
/// turn progressive evaluation flag on/off
inline bool setProgressiveEvalFlag(bool f) {
bool oldf = progressiveEvalFlag;
progressiveEvalFlag = f;
bool oldf = get_static_progressiveEvalFlag();
get_static_progressiveEvalFlag() = f;
return oldf;
}
/// set initial bit precision for progressive evaluation:
inline long setDefInitialProgressivePrec(long n) {
long oldn = defInitialProgressivePrec;
defInitialProgressivePrec = n;
long oldn = get_static_defInitialProgressivePrec();
get_static_defInitialProgressivePrec() = n;
return oldn;
}
/// turn rational reduction flag on/off
inline bool setRationalReduceFlag(bool f) {
bool oldf = rationalReduceFlag;
rationalReduceFlag = f;
bool oldf = get_static_rationalReduceFlag();
get_static_rationalReduceFlag() = f;
return oldf;
}
@ -235,9 +261,9 @@ inline bool setRationalReduceFlag(bool f) {
e.g., overriding the default std::cout precision (most systems
initializes this value to 6) to our own */
inline void CORE_init(long d) {
defAbsPrec = CORE_posInfty;
defOutputDigits = d;
std::setprecision(defOutputDigits);
get_static_defAbsPrec() = CORE_posInfty;
get_static_defOutputDigits() = d;
std::setprecision(get_static_defOutputDigits());
}
/// change to scientific output format
@ -251,4 +277,9 @@ inline void setPositionalFormat(std::ostream& o = std::cout) {
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/CoreDefs_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_COREDEFS_H_

View File

@ -0,0 +1,170 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: CoreDefs.cpp
* Synopsis:
* Useful parameters for Core Library which users may change
*
* Written by
* Chee Yap <yap@cs.nyu.edu>
* Chen Li <chenli@cs.nyu.edu>
* Zilin Du <zilin@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#include "CGAL/CORE/CoreDefs.h"
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
// Default Values
/* ************************************************************
* ERROR FLAGS
* ************************************************************ */
#ifndef CGAL_HEADER_ONLY
/** I/O error flag (Default value 0, indicating no error)
* User's responsibility to check and reset value to 0. */
// This is currently used in geom2d/points2d.cpp for I/O of points
// Note from 2014: does not seem to be used anywhere, and it is not declared
// in CoreDefs.h so it is not accessible
// Left here for compatibilty when CGAL_HEADER_ONLY is not defined
int IOErrorFlag = 0;
/**
* If AbortFlag is true when invalid expression is constructed, system will abort
*/
bool AbortFlag = true;
/**
* InvalidFlag is set to negative whenever an invalid expression is constructed.
* The user has the responsibility to reset to non-negative value.
*/
int InvalidFlag = 0;
/* ************************************************************
* PRECISION PARAMETERS
* ************************************************************ */
/**
* Default BigFloat Division Relative Precision
* -- this is used by BigFloat division when the arguments are error-free.
*/
extLong defBFdivRelPrec = 54;
/**
* Default BigFloat Sqrt Absolute Precision
* -- this is used by BigFloat sqrt when the argument is error-free.
*/
extLong defBFsqrtAbsPrec = 54;
/**
* Escape Precision
* -- we will not compare a number to precision higher than this
* -- if this is infinity, there there is no escape precision */
extLong EscapePrec = CORE_posInfty;
/** this flag becomes negative if the EscapePrec is used. */
long EscapePrecFlag = 0;
/// Escape Precision Warning Flag
/** this flag is true by default, and will cause a warning to be printed
when EscapePrec is reached */
bool EscapePrecWarning = true;
/** The Composite Precision [defAbsPrec, defRelPrec]
* determines the precision to which an Expr evaluates its
* (exact, implicit) constant value. */
/** absolute precision = 2^31 - 1 */
extLong defAbsPrec = CORE_posInfty;
/** default relative precision is 60 relative bits.
* Why 60? We would really like this to be 54, so that the default
* conversion duplicates the IEEE double precision. But it turns out
* (see README file under BUGS), we need 59 to ensure this.
* Chee Yap (7/1/01) */
extLong defRelPrec = 60;
/** number of BigFloat digits to print out */
long defBigFloatOutputDigits = 10;
/** NORMALLY, we like to make this equal to defBigFloatOutputDigits
* 8/3/01, Chee: re-introduced this parameter */
long defOutputDigits = defBigFloatOutputDigits;
/** String Input Precision */
/** Set this to 16 if you want machine precision. This controls the
* absolute error in string decimal inputs to Real or Expr.
* If defInputDigits is finite, then the absolute error will be
* at most 10^{-defInputDigits}. Otherwise, the input is exactly
* represented by some BigFloat or BigRat value. */
extLong defInputDigits = CORE_posInfty;
/** This controls the absolute error in converting from string to BigFloat
* The absolute error will be at most 10^{-defInputDigits} */
long defBigFloatInputDigits = 16;
/* ************************************************************
* EVALUATION FLAGS
* ************************************************************ */
/** Floating Point filter
* true = turn on floating point filter */
bool fpFilterFlag = true;
/** IncrementaL evaluation flag
* incremental evaluation is requested, This means, we try to use previous
* approximate values to improve an approximation */
bool incrementalEvalFlag = true;
/** Progressive evaluation flag
* true = turn on progressive evaluation flag */
bool progressiveEvalFlag = true;
/** Initial progressive evaluation precision
* Used by AddSubRep */
long defInitialProgressivePrec = 64;
/** RATIONAL REDUCTION FLAG
* true = turn on rational reduction */
bool rationalReduceFlag = false;
#endif // CGAL_HEADER_ONLY
} //namespace CORE

View File

@ -0,0 +1,488 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: CoreIO.cpp
*
* Written by
* Zilin Du <zilin@cs.nyu.edu>
* Chee Yap <yap@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#ifndef _COREIO_IMPL_H_
#define _COREIO_IMPL_H_
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#ifdef CGAL_HEADER_ONLY
#define CGAL_HEADERONLY_STATIC_FUNCTION static
#else
#define CGAL_HEADERONLY_STATIC_FUNCTION
#endif
#include <CGAL/CORE/BigFloatRep.h>
#include <CGAL/CORE/BigFloat.h>
#include <CGAL/CORE/BigInt.h>
namespace CORE {
CGAL_HEADERONLY_STATIC_FUNCTION
void core_io_error_handler(const char *f, const char *m) {
std::cout << "\n error_handler";
std::cout << "::" << f << "::" << m << "\n";
std::cout.flush();
std::abort();
}
CGAL_HEADERONLY_STATIC_FUNCTION
void core_io_memory_handler(char *t, const char *f, const char *m) {
if (t == NULL) {
std::cout << "\n memory_handler";
std::cout << "::" << f << "::" << m;
std::cout << "memory exhausted\n";
std::cout.flush();
std::abort();
}
}
// s has size old_size and will be resized to new_size.
CGAL_HEADERONLY_STATIC_FUNCTION
void allocate (char * &s, int old_size, int new_size) {
if (old_size > new_size)
old_size = new_size;
if (s == NULL)
old_size = 0;
char *t = new char[new_size];
core_io_memory_handler(t, "CoreIO", "allocate::out of memory error");
int i;
for (i = 0; i < old_size; i++)
t[i] = s[i];
delete[] s;
s = t;
}
// appends c to s at position pos.
// sz is the size of s
CGAL_HEADERONLY_STATIC_FUNCTION
void append_char (char * &s, int & sz, int pos, char c) {
if (pos > sz)
core_io_error_handler("CoreIO", "append_char::invalid argument");
if (pos == sz) {
allocate(s, sz, 2*sz);
sz *= 2;
}
s[pos] = c;
}
// skip blanks, tabs, line breaks and comment lines
CGAL_HEADERONLY_STATIC_FUNCTION
int skip_comment_line (std::istream & in) {
int c;
do {
c = in.get();
while ( c == '#' ) {
do {
c = in.get();
} while ( c != '\n' );
c = in.get();
}
} while (c == ' ' || c == '\t' || c == '\n');
if (c == EOF)
core_io_error_handler("CoreIO::read_from_file()","unexpected end of file.");
in.putback(c);
return c;
}
// skips '\\' followed by '\n'
CGAL_HEADERONLY_STATIC_FUNCTION
int skip_backslash_new_line (std::istream & in) {
int c = in.get();
while (c == '\\') {
c = in.get();
if (c == '\n')
c = in.get();
else
core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line.");
}
return c;
}
CGAL_HEADERONLY_STATIC_FUNCTION
void read_string(std::istream& in, char* &buffer, int sz) {
int c, pos=0;
skip_comment_line(in);
while ( (c = in.get()) != EOF ) {
if ( c == ' ' || c == '\t' || c == '\n' || c == '#')
break;
else
append_char(buffer, sz, pos++, c);
}
append_char(buffer, sz, pos, '\0');
}
CGAL_HEADERONLY_STATIC_FUNCTION
void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
char *buffer;
int size, offset;
int base;
bool is_negate;
int c, pos = 0;
skip_comment_line(in);
// read sign
c = in.get();
if (c == '-') {
is_negate = true;
c = in.get();
} else
is_negate = false;
// read base and compute digits
if (c == '0') {
c = in.get();
if (c == 'b') {
base = 2;
size = (maxBits == 0 || maxBits > length) ? length : maxBits;
offset = length - size;
} else if (c == 'x') {
base = 16;
size = (maxBits == 0) ? length : (maxBits+3) >> 2;
size = (size > length) ? length : size;
offset = (length - size) << 2;
} else {
base = 8;
size = (maxBits == 0) ? length : (maxBits+2) / 3;
size = (size > length) ? length : size;
offset = (length - size) * 3;
in.putback(c);
}
} else {
base = 10;
size = (maxBits == 0) ? length : (int)std::ceil(maxBits*std::log(2.0)/std::log(10.0));
size = (size > length) ? length : size;
offset = length - size;
in.putback(c);
}
buffer = new char[size+2];
// read digits
for (int i=0; (i<size)&&((c=skip_backslash_new_line(in)) != EOF ); i++) {
if (c != ' ' && c != '\t' && c != '\n')
append_char(buffer, size, pos++, c);
}
if (base == 10) {
for(int j=0; j<offset; j++)
append_char(buffer, size, pos++, '0');
}
append_char(buffer, size, pos, '\0');
// convert string to bigint.
if (m.set_str(buffer, base) < 0)
core_io_error_handler("CoreIO::read_from_file()","bad big number format.");
delete[] buffer;
// shift left if neccessary
if (offset > 0 && base != 10) {
m <<= offset;
}
if (is_negate)
negate(m);
}
CGAL_HEADERONLY_STATIC_FUNCTION
void write_base_number(std::ostream& out, char* buffer, int length, int base, int charsPerLine) {
// write big number in a format that gmp's mpz_set_str() can
// automatically recognize with argument base = 0.
if (base == 2)
out << "0b";
else if (base == 16)
out << "0x";
else if (base == 8)
out << '0';
// write big number in charsPerLine.
char* start, *end, c;
for (int i=0; i<length; i += charsPerLine) {
start = buffer + i;
if (i + charsPerLine >= length)
out << start;
else {
end = start + charsPerLine;
c = *end;
*end = '\0';
out << start << "\\\n";
*end = c;
}
}
}
CGAL_INLINE_FUNCTION
void readFromFile(BigInt& z, std::istream& in, long maxLength) {
char *buffer;
long length;
// check type name whether it is Integer or not.
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if ( std::strcmp(buffer, "Integer") != 0)
core_io_error_handler("BigInt::read_from_file()","type name expected.");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read bigint
read_base_number(in, z, length, maxLength);
}
CGAL_INLINE_FUNCTION
void writeToFile(const BigInt& z, std::ostream& out, int base, int charsPerLine) {
BigInt c = abs(z);
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name of big number and length
//out << "# This is an experimental big number format.\n";
out << "Integer " << length << "\n";
// if bigint is negative, then write an sign '-'.
if ( sign(z) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << "\n";
delete[] buffer;
}
CGAL_INLINE_FUNCTION
void readFromFile(BigFloat& bf, std::istream& in, long maxLength) {
char *buffer;
long length;
long exponent;
BigInt mantissa;
// check type name whether it is Float
buffer = new char[6];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "Float") != 0)
core_io_error_handler("BigFloat::read_from_file()", "type name expected");
delete[] buffer;
// read base (default is 16384)
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "(16384)") != 0)
core_io_error_handler("BigFloat::read_from_file()", "base expected");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read exponent
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
exponent = std::atol(buffer);
delete[] buffer;
// read mantissa
read_base_number(in, mantissa, length, maxLength);
// construct BigFloat
bf = BigFloat(mantissa, 0, exponent);
}
CGAL_INLINE_FUNCTION
void writeToFile(const BigFloat& bf, std::ostream& out, int base, int charsPerLine) {
BigInt c(CORE::abs(bf.m()));
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name, base, length
//out << "# This is an experimental Big Float format." << std::endl;
out << "Float (16384) " << length << std::endl;
// write exponent
out << bf.exp() << std::endl;
// write mantissa
if ( CORE::sign(bf.m()) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
/* Underconstruction ----
void BigFloat::read_from_file2(std::istream& in, long maxLength) {
long length = 1024;
char *buffer;
// check type name whether it is Float
buffer = new char[7];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "NFloat") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "type name expected");
delete[] buffer;
// read base (default is 16)
buffer = new char[5];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "(16)") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "base expected");
delete[] buffer;
// read length field
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
// get the length field if it is not null.
if (buffer[0] != '\0') {
length = atol(buffer);
if (maxLength > 0 && length >= maxLength)
length = maxLength;
}
delete[] buffer;
// read exponent
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
long exp16 = atol(buffer);
delete[] buffer;
// read mantissa
buffer = new char[length+2];
//BigInt::read_base_number(in, buffer, length);
BigInt m16(buffer);
delete[] buffer;
// convert to base CHUNK_BIT
exp16 = exp16 - length + 1;
if ( m16.is_negative() )
exp16 ++;
long tmp_exp = exp16 * 4;
long q = tmp_exp / CHUNK_BIT;
long r = tmp_exp % CHUNK_BIT;
if ( r < 0 ) {
r += CHUNK_BIT;
q --;
}
BigInt mantissa = m16 << r;
long exponent = q;
// construct BigFloat
if (--rep->refCount == 0)
delete rep;
rep = new BigFloatRep(mantissa, 0, exponent);
rep->refCount++;
}
// write normal float
// now it assumed to write in hex base, i.e. B=2^4=16
// (note: our default base B=2^(CHUNK_BIT)=2^14=16384
void BigFloat::write_to_file2(std::ostream& out, int base, int charsPerLine) {
// convert to base 16.
long new_base = 4; // 2^4 = 16
long tmp_exp = (rep->exp) * CHUNK_BIT;
long q = tmp_exp / new_base;
long r = tmp_exp % new_base;
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
if ( r < 0 ) {
r += new_base;
q--;
}
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
BigInt m16 = (rep->m) << r;
int size = mpz_sizeinbase(m16.I, base) + 2;
std::cout << "size=" << size << std::endl;
char* buffer = new char[size];
int length = bigint_to_string(m16, buffer, base);
std::cout << "length=" << length << std::endl;
long exp16 = q + length - 1;
if ( m16.is_negative() )
exp16 --;
// write type name, base, length
out << "# This is an experimental Big Float format." << std::endl;
out << "NFloat (16) " << length << std::endl;
// write exponent
out << exp16 << std::endl;
// write mantissa
if ( m16.is_negative() ) {
out << '-';
buffer ++;
}
BigInt::write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
*/
} //namespace CORE
#endif // _COREIO_IMPL_H_

View File

@ -36,11 +36,22 @@
* $Id$
***************************************************************************/
// We need to include BigFloat.h here because there is a circular dependency
// between Expr and BigFloat.
#include <CGAL/CORE/BigFloat.h>
#ifndef _CORE_EXPR_H_
#define _CORE_EXPR_H_
#include <CGAL/CORE/ExprRep.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
/// \class Expr Expr.h
@ -78,9 +89,9 @@ public:
// (i.e., not infinite and not NaN)
if (! CGAL_CORE_finite(f)) {
std::cerr << " ERROR : constructed an invalid float! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -1;
get_static_InvalidFlag() = -1;
}
rep = new ConstDoubleRep(f);
}
@ -89,9 +100,9 @@ public:
// (i.e., not infinite and not NaN)
if (! CGAL_CORE_finite(d)) {
std::cerr << " ERROR : constructed an invalid double! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -2;
get_static_InvalidFlag() = -2;
}
rep = new ConstDoubleRep(d);
}
@ -111,11 +122,11 @@ public:
* it is generally recommended that the (String) constructor be used in
* preference to the (double) constructor.
*/
Expr(const char *s, const extLong& p = defInputDigits)
Expr(const char *s, const extLong& p = get_static_defInputDigits())
: RCExpr(new ConstRealRep(Real(s, p))) {}
/// constructor for <tt>std::string</tt>
Expr(const std::string& s, const extLong& p = defInputDigits)
Expr(const std::string& s, const extLong& p = get_static_defInputDigits())
: RCExpr(new ConstRealRep(Real(s, p))) {}
/// constructor for <tt>Real</tt>
@ -179,9 +190,9 @@ public:
Expr& operator/=(const Expr& e) {
if ((e.rep)->getSign() == 0) {
std::cerr << " ERROR : division by zero ! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -3;
get_static_InvalidFlag() = -3;
}
*this = new DivRep(rep, e.rep);
return *this;
@ -225,12 +236,12 @@ public:
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt>
void fromString(const char* s, const extLong& prec = defInputDigits) {
void fromString(const char* s, const extLong& prec = get_static_defInputDigits()) {
*this = Expr(s, prec);
}
/// convert to <tt>std::string</tt>
/** give decimal string representation */
std::string toString(long prec=defOutputDigits, bool sci=false) const {
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) const {
return rep->toString(prec, sci);
}
//@}
@ -282,8 +293,8 @@ public:
/** Here is the definition of what this means:
If e is the exact value and ee is the approximate value,
then |e - ee| <= 2^{-a} or |e - ee| <= 2^{-r} |e|. */
const Real & approx(const extLong& relPrec = defRelPrec,
const extLong& absPrec = defAbsPrec) const {
const Real & approx(const extLong& relPrec = get_static_defRelPrec(),
const extLong& absPrec = get_static_defAbsPrec()) const {
return rep->getAppValue(relPrec, absPrec);
}
//@}
@ -355,7 +366,7 @@ inline std::ostream& operator<<(std::ostream& o, const Expr& e) {
/// I/O Stream operator>>
inline std::istream& operator>>(std::istream& i, Expr& e) {
Real rVal;
i >> rVal; // precision is = defInputDigits
i >> rVal; // precision is = get_static_defInputDigits()
if (i)
e = rVal; // only assign when reading is successful.
return i;
@ -382,9 +393,9 @@ inline Expr operator*(const Expr& e1, const Expr& e2) {
inline Expr operator/(const Expr& e1, const Expr& e2) {
if (e2.sign() == 0) {
std::cerr << " ERROR : division by zero ! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -4;
get_static_InvalidFlag() = -4;
}
return Expr(new DivRep(e1.Rep(), e2.Rep()));
}
@ -485,9 +496,9 @@ inline bool isDivisible(const Expr& e1, const Expr& e2) {
inline Expr sqrt(const Expr& e) {
if (e.sign() < 0) {
std::cerr << " ERROR : sqrt of negative value ! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -5;
get_static_InvalidFlag() = -5;
}
return Expr(new SqrtRep(e.Rep()));
}
@ -548,4 +559,9 @@ inline Expr radical(const NT& n, int m) {
#include <CGAL/CORE/poly/Poly.tcc>
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/Expr_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_EXPR_H_

View File

@ -43,9 +43,16 @@
#include <CGAL/CORE/Filter.h>
#include <CGAL/CORE/poly/Sturm.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
#ifdef CORE_DEBUG_BOUND
#if defined(CORE_DEBUG_BOUND) && !defined(CGAL_HEADER_ONLY)
// These counters are incremented each time each bound is recognized as equal
// to the best one in computeBound().
extern unsigned int BFMSS_counter;
@ -189,8 +196,8 @@ public:
/// \name Helper Functions
//@{
/// Get the approximate value
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = defRelPrec,
const extLong& absPrec = defAbsPrec);
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = get_static_defRelPrec(),
const extLong& absPrec = get_static_defAbsPrec());
/// Get the sign.
int getSign();
int getExactSign();
@ -389,8 +396,8 @@ public:
BigFloat BigFloatValue();
/// represent as a string in decimal value
// toString() Joaquin Grech 31/5/2003
std::string toString(long prec=defOutputDigits, bool sci=false) {
return (getAppValue(defRelPrec, defAbsPrec)).toString(prec,sci);
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) {
return (getAppValue(get_static_defRelPrec(), get_static_defAbsPrec())).toString(prec,sci);
}
//@}
@ -677,7 +684,7 @@ protected:
tc() = ceilLg(ss.seq[0].getTailCoeff());
// no rational reduction
if (rationalReduceFlag)
if (get_static_rationalReduceFlag())
ratFlag() = -1;
flagsComputed() = true;
@ -838,7 +845,12 @@ protected:
/// \brief "functor" class used as parameter to AddSubRep<>
struct Add {
/// name
#ifndef CGAL_HEADER_ONLY
CGAL_CORE_EXPORT static const char* name;
#endif
static const char* get_name() {
return "+";
}
/// unary operator
template <class T>
@ -857,7 +869,12 @@ struct Add {
/// \brief "functor" class used as parameter to AddSubRep<>
struct Sub {
/// name
#ifndef CGAL_HEADER_ONLY
CGAL_CORE_EXPORT static const char* name;
#endif
static const char* get_name() {
return "-";
}
/// unary operator
template <class T>
@ -895,7 +912,7 @@ protected:
void computeApproxValue(const extLong&, const extLong&);
/// return operator in string
const std::string op() const {
return Operator::name;
return Operator::get_name();
}
private:
static Operator Op;
@ -925,7 +942,7 @@ void AddSubRep<Operator>::computeExactFlags() {
reduceTo(second);
sign() = Op(ss);
appValue() = Op(appValue());
if (rationalReduceFlag && ratFlag() > 0)
if (get_static_rationalReduceFlag() && ratFlag() > 0)
*(ratValue()) = Op(*(ratValue()));
return;
} else if (ss == 0) { // second operand is zero
@ -933,7 +950,7 @@ void AddSubRep<Operator>::computeExactFlags() {
return;
}
// rational node
if (rationalReduceFlag) {
if (get_static_rationalReduceFlag()) {
if (first->ratFlag() > 0 && second->ratFlag() > 0) {
BigRat val=Op(*(first->ratValue()), *(second->ratValue()));
reduceToBigRat(val);
@ -1046,7 +1063,7 @@ void AddSubRep<Operator>::computeExactFlags() {
if (lowBound <= EXTLONG_ZERO)
lowBound = EXTLONG_ONE;
if (!progressiveEvalFlag) {
if (!get_static_progressiveEvalFlag()) {
// convert the absolute error requirement "lowBound" to
// a relative error requirement "ur", s.t.
// |x|*2^(-ur) <= 2^(-lowBound).
@ -1085,7 +1102,7 @@ void AddSubRep<Operator>::computeExactFlags() {
// larger than lowBound AND the defaultInitialProgressivePrec,
// so that we do at least one iteration of the for-loop. So:
// i is the variable for iteration.
extLong i = core_min(defInitialProgressivePrec, lowBound.asLong());
extLong i = core_min(get_static_defInitialProgressivePrec(), lowBound.asLong());
extLong ua = lowBound.asLong() + EXTLONG_ONE;
// NOTE: ua is allowed to be CORE_INFTY
@ -1096,7 +1113,7 @@ void AddSubRep<Operator>::computeExactFlags() {
lMSB() = CORE_negInfty;
sign() = 0;
EscapePrecFlag = 0; // reset the Escape Flag
get_static_EscapePrecFlag() = 0; // reset the Escape Flag
// Now we try to determine the real lMSB and sign,
// in case it is not really zero:
@ -1151,22 +1168,22 @@ void AddSubRep<Operator>::computeExactFlags() {
break; // assert -- this must happen in the loop if nonzero!
}
//8/9/01, Chee: implement escape precision here:
if (i> EscapePrec) {
EscapePrecFlag = -i.asLong();//negative means EscapePrec is used
if (i> get_static_EscapePrec()) {
get_static_EscapePrecFlag() = -i.asLong();//negative means EscapePrec is used
core_error("Escape precision triggered at",
__FILE__, __LINE__, false);
if (EscapePrecWarning)
if (get_static_EscapePrecWarning())
std::cout<< "Escape Precision triggered at "
<< EscapePrec << " bits" << std::endl;
<< get_static_EscapePrec() << " bits" << std::endl;
#ifdef CORE_DEBUG
std::cout << "EscapePrecFlags=" << EscapePrecFlag << std::endl;
std::cout << "EscapePrecFlags=" << get_static_EscapePrecFlag() << std::endl;
std::cout << "ua =" << ua << ",lowBound=" << lowBound << std::endl;
#endif
break;
}// if
}// for (long i=1...)
#ifdef CORE_DEBUG_BOUND
#if defined(CORE_DEBUG_BOUND) && !defined(CGAL_HEADER_ONLY)
rootBoundHitCounter++;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,13 @@
#include <CGAL/CORE/Real.h>
#include <cmath>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
#if !defined CGAL_CFG_NO_CPP0X_ISFINITE
#define CGAL_CORE_finite(x) std::isfinite(x)
#elif defined (_MSC_VER) || defined (__MINGW32__) // add support for MinGW
@ -102,7 +109,7 @@ public:
}
/// check whether the sign (!) of the filtered value is OK
bool isOK() const {
return (fpFilterFlag && // To disable filter
return (get_static_fpFilterFlag() && // To disable filter
CGAL_CORE_finite(fpVal) && // Test for infinite and NaNs
(core_abs(fpVal) >= maxAbs*ind*CORE_EPS));
}

View File

@ -27,6 +27,13 @@
#include <CGAL/CORE/Impl.h>
#include <gmp.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpz_srcptr);
@ -39,4 +46,9 @@ CGAL_CORE_EXPORT std::istream& io_read (std::istream &, mpq_ptr);
//std::istream& operator>> (std::istream &, mpq_ptr);
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/Gmp_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_GMP_H_

View File

@ -0,0 +1,280 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* file: GmpIO.cpp
* Adapted from multi-files under /cxx in GMP's source distribution
*
* Zilin Du, 2003
*
* $URL$
* $Id$
***************************************************************************/
/* Auxiliary functions for C++-style input of GMP types.
Copyright 2001 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/CORE/Gmp.h>
#include <cctype>
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
namespace CORE {
CGAL_INLINE_FUNCTION
int
__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
{
int base;
zero = showbase = false;
switch (i.flags() & ios::basefield)
{
case ios::dec:
base = 10;
break;
case ios::hex:
base = 16;
break;
case ios::oct:
base = 8;
break;
default:
showbase = true; // look for initial "0" or "0x" or "0X"
if (c == '0')
{
if (! i.get(c))
c = 0; // reset or we might loop indefinitely
if (c == 'x' || c == 'X')
{
base = 16;
i.get(c);
}
else
{
base = 8;
zero = true; // if no other digit is read, the "0" counts
}
}
else
base = 10;
break;
}
return base;
}
CGAL_INLINE_FUNCTION
void
__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
{
switch (base)
{
case 10:
while (isdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 8:
while (isdigit(c) && c != '8' && c != '9')
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 16:
while (isxdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
}
}
CGAL_INLINE_FUNCTION
istream &
//operator>> (istream &i, mpz_ptr z)
io_read (istream &i, mpz_ptr z)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-') // mpz_set_str doesn't accept '+'
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the number
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && (ok || zero)) // stopped just before eof
i.clear();
if (ok)
mpz_set_str(z, s.c_str(), base); // extract the number
else if (zero)
mpz_set_ui(z, 0);
else
i.setstate(ios::failbit); // read failed
return i;
}
CGAL_INLINE_FUNCTION
istream &
//operator>> (istream &i, mpq_ptr q)
io_read (istream &i, mpq_ptr q)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-')
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the numerator
if (! ok && zero) // the only digit read was "0"
{
base = 10;
s += '0';
ok = true;
}
if (i.flags() & ios::skipws)
while (isspace(c) && i.get(c)) // skip whitespace
;
if (c == '/') // there's a denominator
{
bool zero2 = false;
int base2 = base;
s += '/';
ok = false; // denominator is mandatory
i.get(c);
while (isspace(c) && i.get(c)) // skip whitespace
;
if (showbase) // check base of denominator
base2 = __gmp_istream_set_base(i, c, zero2, showbase);
if (base2 == base || base2 == 10) // read the denominator
__gmp_istream_set_digits(s, i, c, ok, base);
if (! ok && zero2) // the only digit read was "0"
{ // denominator is 0, but that's your business
s += '0';
ok = true;
}
}
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && ok) // stopped just before eof
i.clear();
if (ok)
mpq_set_str(q, s.c_str(), base); // extract the number
else
i.setstate(ios::failbit); // read failed
return i;
}
CGAL_INLINE_FUNCTION
ostream&
//operator<< (ostream &o, mpz_srcptr z)
io_write (ostream &o, mpz_srcptr z)
{
char *str = new char [mpz_sizeinbase(z,10) + 2];
str = mpz_get_str(str, 10, z);
o << str ;
delete[] str;
return o;
}
CGAL_INLINE_FUNCTION
ostream&
//operator<< (ostream &o, mpq_srcptr q)
io_write (ostream &o, mpq_srcptr q)
{
// size according to GMP documentation
char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) +
mpz_sizeinbase (mpq_denref(q), 10) + 3];
str = mpq_get_str(str, 10, q);
o << str ;
delete[] str;
return o;
}
} //namespace CORE

View File

@ -39,6 +39,13 @@
#define _CORE_REAL_H_
#include "RealRep.h"
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
// class Real
typedef RCImpl<RealRep> RCReal;
@ -57,10 +64,10 @@ public:
Real(const BigInt& I) : RCReal(new RealBigInt(I)) {}
Real(const BigRat& R) : RCReal(new RealBigRat(R)) {}
Real(const BigFloat& F) : RCReal(new RealBigFloat(F)) {}
Real(const char* s, const extLong& prec=defInputDigits) : RCReal(NULL) {
Real(const char* s, const extLong& prec=get_static_defInputDigits()) : RCReal(NULL) {
constructFromString(s, prec);
}
Real(const std::string& s, const extLong& prec=defInputDigits) : RCReal(NULL){
Real(const std::string& s, const extLong& prec=get_static_defInputDigits()) : RCReal(NULL){
constructFromString(s.c_str(), prec);
}
@ -134,12 +141,12 @@ public:
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt>
void fromString(const char* s, const extLong& prec = defInputDigits) {
void fromString(const char* s, const extLong& prec = get_static_defInputDigits()) {
*this = Real(s, prec);
}
/// convert to <tt>std::string</tt>
/** give decimal string representation */
std::string toString(long prec=defOutputDigits, bool sci=false) const {
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) const {
return rep->toString(prec, sci);
}
//@}
@ -179,7 +186,8 @@ public:
/// \name Aprroximation Function
//@{
/// approximation
Real approx(const extLong& r=defRelPrec, const extLong& a=defAbsPrec) const {
Real approx(const extLong& r=get_static_defRelPrec(),
const extLong& a=get_static_defAbsPrec()) const {
return rep->approx(r, a);
}
//@}
@ -395,7 +403,7 @@ inline Real& Real::operator*=(const Real& rhs) {
return *this;
}
inline Real& Real::operator/=(const Real& rhs) {
*this = real_div::eval(getRep(), rhs.getRep(), defRelPrec);
*this = real_div::eval(getRep(), rhs.getRep(), get_static_defRelPrec());
return *this;
}
@ -413,7 +421,7 @@ inline Real operator*(const Real& x, const Real& y) {
}
// operator/
inline Real operator/(const Real& x, const Real& y) {
return real_div::eval(x.getRep(), y.getRep(), defRelPrec);
return real_div::eval(x.getRep(), y.getRep(), get_static_defRelPrec());
}
// div w/ precision
inline Real Real::div(const Real& x, const extLong& r) const {
@ -478,7 +486,7 @@ inline Real power(const Real& r, unsigned long p) {
}
/// square root
inline Real sqrt(const Real& x) {
return x.sqrt(defAbsPrec);
return x.sqrt(get_static_defAbsPrec());
}
// class Realbase_for (need defined after Real)
@ -493,4 +501,9 @@ inline Real RealLong::operator-() const {
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/Real_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_REAL_H_

View File

@ -41,6 +41,13 @@
#include <CGAL/CORE/Impl.h>
#include <CGAL/CORE/CoreAux.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
#ifndef LONG_MAX
@ -294,4 +301,9 @@ inline bool extLong::isNaN() const {
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/extLong_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_EXTLONG_H_

View File

@ -205,7 +205,8 @@ public:
/// Polynomial evaluation where the coefficients are approximated first
/// Returns a BigFloat with error that contains the value
BigFloat evalApprox(const BigFloat& f,
const extLong& r=defRelPrec, const extLong& a=defAbsPrec) const;
const extLong& r=get_static_defRelPrec(),
const extLong& a=get_static_defAbsPrec()) const;
/// Polynomial evaluation at a BigFloat value.
/// The returned BigFloat (with error) has the exact sign.
/// In particular, if the value is 0, we return 0.

File diff suppressed because it is too large Load Diff

View File

@ -33,181 +33,9 @@
* $Id$
***************************************************************************/
#include "CGAL/CORE/CoreAux.h"
#include <gmp.h>
#ifndef CGAL_HEADER_ONLY
namespace CORE {
#include <CGAL/CORE/CoreAux.h>
#include <CGAL/CORE/CoreAux_impl.h>
////////////////////////////////////////////////////////////
// More useful functions to implement:
//
// To convert digits into bits:
// given X, compute X * log_2(10)
// To convert bits into digits:
// given X, compute X * log_10(2)
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// flrLg(x)
// returns floor log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
int flrLg(long x) {
if (x == LONG_MIN) {
// special treatment as -LONG_MIN would be not representable as "long"
return LONG_BIT - 1;
} else {
// 1 <= |x| <= LONG_MAX
if (x < 0)
x = - x;
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
}
////////////////////////////////////////////////////////////
// floor log base 2 of unsigned long x
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
int flrLg(unsigned long x) {
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
int clLg(long x) {
if (x == LONG_MIN)
return LONG_BIT - 1;
if (x < 0)
x = -x; // use absolute value
if (x > (LONG_MAX >> 1)) // the leading data bit is 1
return (LONG_BIT - 1); // exclude the sign bit
if (x >= 2)
return flrLg((unsigned long)((x << 1) - 1));
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2
if (x == 1)
return 0;
return -1; // x must be 0 here
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of unsigned long x
// CONVENTION lg(0) = -1
////////////////////////////////////////////////////////////
int clLg(unsigned long x) {
if (x > (ULONG_MAX >> 1)) // the leading bit is 1
return LONG_BIT;
if (x >= 2)
return flrLg((x << 1) - 1);
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2.
if (x == 1)
return 0;
return -1; // x must be equal to 0
}
/// gcd for machine type long
/** This is needed when we construct Polynomials with int or long coefficients */
long gcd(long m, long n) {
if (m == 0)
return core_abs(n);
if (n == 0)
return core_abs(m);
long p = core_abs(m);
long q = core_abs(n);
if (p<q)
core_swap(p, q);
while (q>0) {
long r = p % q;
p = q;
q = r;
}
return p;
}
// return a gmp_randstate_t structure
gmp_randstate_t* getRandstate() {
static gmp_randstate_t rstate;
static bool initialized = false;
if (!initialized) {
gmp_randinit(rstate, GMP_RAND_ALG_DEFAULT, 32L);
initialized = true;
}
return &rstate;
}
// char* core_itoa(int n, char* buffer)
// returns a pointer to the null-terminated string in buffer
// NOTES:
// 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit
// (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes.
// 1. itoa(...) is available on some stdlib.h, but it is
// not defined by ANSI-C and so not all compilers support it.
// 2. Our use of sprintf(...) to do the job is known to
// be inefficient, but this is hardly critical for our usage.
// 3. A more general program should take a 3rd argument (the radix of
// output number). We assume radix 10.
char * core_itoa(int n, char* buffer) {
std::sprintf(buffer, "%d", n);
return buffer;
}
/// implements the "integer mantissa" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
double IntMantissa(double d) {
int e;
return std::ldexp(std::frexp(d, &e), 53);
}
/// implements the "integer exponent" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
int IntExponent(double d) {
int e;
std::frexp(d, &e);
return e-53;
}
/// CORE_DIAGFILE is file name for core_error(..) output.
const char* CORE_DIAGFILE = "Core_Diagnostics"; // global file name
/// core_error is the method to write Core Library warning or error messages
/** Both warnings and errors are written to a file called CORE_DIAGFILE.
* But errors are also written on std:cerr (similar to std::perror()).
* */
// Usage: core_error(message, file_with_error, line_number, err_type)
// where err_type=0 means WARNING, error_type=0 means ERROR
void core_error(std::string msg, std::string file, int lineno, bool err) {
std::ofstream outFile(CORE_DIAGFILE, std::ios::app); // open to append
if (!outFile) {
// perror("CORE ERROR: cannot open Core Diagnostics file");
std::cerr << "CORE ERROR: can't open Core Diagnostics file"<<std::endl;
std::exit(1); //Note: do not call abort()
}
outFile << "CORE " << (err? "ERROR" : "WARNING")
<< " (at " << file << ": " << lineno << "): "
<< msg << std::endl;
outFile.close();
if (err) {
char buf[65];
// perror((std::string("CORE ERROR") + " (file " + file + ", line "
// + core_itoa(lineno,buf) +"):" + msg + "\n").c_str());
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
+ core_itoa(lineno,buf) +"):" + msg + "\n").c_str();
std::exit(1); //Note: do not call abort()
}
}
} //namespace CORE
#endif

View File

@ -32,124 +32,9 @@
* $Id$
***************************************************************************/
#include "CGAL/CORE/CoreDefs.h"
#ifndef CGAL_HEADER_ONLY
namespace CORE {
// Default Values
/* ************************************************************
* ERROR FLAGS
* ************************************************************ */
/** I/O error flag (Default value 0, indicating no error)
* User's responsibility to check and reset value to 0. */
// This is currently used in geom2d/points2d.cpp for I/O of points
int IOErrorFlag = 0;
/**
* If AbortFlag is true when invalid expression is constructed, system will abort
*/
bool AbortFlag = true;
/**
* InvalidFlag is set to negative whenever an invalid expression is constructed.
* The user has the responsibility to reset to non-negative value.
*/
int InvalidFlag = 0;
/* ************************************************************
* PRECISION PARAMETERS
* ************************************************************ */
/**
* Default BigFloat Division Relative Precision
* -- this is used by BigFloat division when the arguments are error-free.
*/
extLong defBFdivRelPrec = 54;
/**
* Default BigFloat Sqrt Absolute Precision
* -- this is used by BigFloat sqrt when the argument is error-free.
*/
extLong defBFsqrtAbsPrec = 54;
/**
* Escape Precision
* -- we will not compare a number to precision higher than this
* -- if this is infinity, there there is no escape precision */
extLong EscapePrec = CORE_posInfty;
/** this flag becomes negative if the EscapePrec is used. */
long EscapePrecFlag = 0;
/// Escape Precision Warning Flag
/** this flag is true by default, and will cause a warning to be printed
when EscapePrec is reached */
bool EscapePrecWarning = true;
/** The Composite Precision [defAbsPrec, defRelPrec]
* determines the precision to which an Expr evaluates its
* (exact, implicit) constant value. */
/** absolute precision = 2^31 - 1 */
extLong defAbsPrec = CORE_posInfty;
/** default relative precision is 60 relative bits.
* Why 60? We would really like this to be 54, so that the default
* conversion duplicates the IEEE double precision. But it turns out
* (see README file under BUGS), we need 59 to ensure this.
* Chee Yap (7/1/01) */
extLong defRelPrec = 60;
/** number of BigFloat digits to print out */
long defBigFloatOutputDigits = 10;
/** NORMALLY, we like to make this equal to defBigFloatOutputDigits
* 8/3/01, Chee: re-introduced this parameter */
long defOutputDigits = defBigFloatOutputDigits;
/** String Input Precision */
/** Set this to 16 if you want machine precision. This controls the
* absolute error in string decimal inputs to Real or Expr.
* If defInputDigits is finite, then the absolute error will be
* at most 10^{-defInputDigits}. Otherwise, the input is exactly
* represented by some BigFloat or BigRat value. */
extLong defInputDigits = CORE_posInfty;
/** This controls the absolute error in converting from string to BigFloat
* The absolute error will be at most 10^{-defInputDigits} */
long defBigFloatInputDigits = 16;
/* ************************************************************
* EVALUATION FLAGS
* ************************************************************ */
/** Floating Point filter
* true = turn on floating point filter */
bool fpFilterFlag = true;
/** IncrementaL evaluation flag
* incremental evaluation is requested, This means, we try to use previous
* approximate values to improve an approximation */
bool incrementalEvalFlag = true;
/** Progressive evaluation flag
* true = turn on progressive evaluation flag */
bool progressiveEvalFlag = true;
/** Initial progressive evaluation precision
* Used by AddSubRep */
long defInitialProgressivePrec = 64;
/** RATIONAL REDUCTION FLAG
* true = turn on rational reduction */
bool rationalReduceFlag = false;
} //namespace CORE
#include <CGAL/CORE/CoreDefs.h>
#include <CGAL/CORE/CoreDefs_impl.h>
#endif

View File

@ -29,430 +29,6 @@
* $Id$
***************************************************************************/
#include <CGAL/CORE/BigFloatRep.h>
#include <CGAL/CORE/BigFloat.h>
namespace CORE {
void core_io_error_handler(const char *f, const char *m) {
std::cout << "\n error_handler";
std::cout << "::" << f << "::" << m << "\n";
std::cout.flush();
std::abort();
}
void core_io_memory_handler(char *t, const char *f, const char *m) {
if (t == NULL) {
std::cout << "\n memory_handler";
std::cout << "::" << f << "::" << m;
std::cout << "memory exhausted\n";
std::cout.flush();
std::abort();
}
}
// s has size old_size and will be resized to new_size.
void allocate (char * &s, int old_size, int new_size) {
if (old_size > new_size)
old_size = new_size;
if (s == NULL)
old_size = 0;
char *t = new char[new_size];
core_io_memory_handler(t, "CoreIO", "allocate::out of memory error");
int i;
for (i = 0; i < old_size; i++)
t[i] = s[i];
delete[] s;
s = t;
}
// appends c to s at position pos.
// sz is the size of s
void append_char (char * &s, int & sz, int pos, char c) {
if (pos > sz)
core_io_error_handler("CoreIO", "append_char::invalid argument");
if (pos == sz) {
allocate(s, sz, 2*sz);
sz *= 2;
}
s[pos] = c;
}
// skip blanks, tabs, line breaks and comment lines
int skip_comment_line (std::istream & in) {
int c;
do {
c = in.get();
while ( c == '#' ) {
do {
c = in.get();
} while ( c != '\n' );
c = in.get();
}
} while (c == ' ' || c == '\t' || c == '\n');
if (c == EOF)
core_io_error_handler("CoreIO::read_from_file()","unexpected end of file.");
in.putback(c);
return c;
}
// skips '\\' followed by '\n'
int skip_backslash_new_line (std::istream & in) {
int c = in.get();
while (c == '\\') {
c = in.get();
if (c == '\n')
c = in.get();
else
core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line.");
}
return c;
}
void read_string(std::istream& in, char* &buffer, int sz) {
int c, pos=0;
skip_comment_line(in);
while ( (c = in.get()) != EOF ) {
if ( c == ' ' || c == '\t' || c == '\n' || c == '#')
break;
else
append_char(buffer, sz, pos++, c);
}
append_char(buffer, sz, pos, '\0');
}
void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
char *buffer;
int size, offset;
int base;
bool is_negate;
int c, pos = 0;
skip_comment_line(in);
// read sign
c = in.get();
if (c == '-') {
is_negate = true;
c = in.get();
} else
is_negate = false;
// read base and compute digits
if (c == '0') {
c = in.get();
if (c == 'b') {
base = 2;
size = (maxBits == 0 || maxBits > length) ? length : maxBits;
offset = length - size;
} else if (c == 'x') {
base = 16;
size = (maxBits == 0) ? length : (maxBits+3) >> 2;
size = (size > length) ? length : size;
offset = (length - size) << 2;
} else {
base = 8;
size = (maxBits == 0) ? length : (maxBits+2) / 3;
size = (size > length) ? length : size;
offset = (length - size) * 3;
in.putback(c);
}
} else {
base = 10;
size = (maxBits == 0) ? length : (int)std::ceil(maxBits*std::log(2.0)/std::log(10.0));
size = (size > length) ? length : size;
offset = length - size;
in.putback(c);
}
buffer = new char[size+2];
// read digits
for (int i=0; (i<size)&&((c=skip_backslash_new_line(in)) != EOF ); i++) {
if (c != ' ' && c != '\t' && c != '\n')
append_char(buffer, size, pos++, c);
}
if (base == 10) {
for(int j=0; j<offset; j++)
append_char(buffer, size, pos++, '0');
}
append_char(buffer, size, pos, '\0');
// convert string to bigint.
if (m.set_str(buffer, base) < 0)
core_io_error_handler("CoreIO::read_from_file()","bad big number format.");
delete[] buffer;
// shift left if neccessary
if (offset > 0 && base != 10) {
m <<= offset;
}
if (is_negate)
negate(m);
}
void write_base_number(std::ostream& out, char* buffer, int length, int base, int charsPerLine) {
// write big number in a format that gmp's mpz_set_str() can
// automatically recognize with argument base = 0.
if (base == 2)
out << "0b";
else if (base == 16)
out << "0x";
else if (base == 8)
out << '0';
// write big number in charsPerLine.
char* start, *end, c;
for (int i=0; i<length; i += charsPerLine) {
start = buffer + i;
if (i + charsPerLine >= length)
out << start;
else {
end = start + charsPerLine;
c = *end;
*end = '\0';
out << start << "\\\n";
*end = c;
}
}
}
void readFromFile(BigInt& z, std::istream& in, long maxLength) {
char *buffer;
long length;
// check type name whether it is Integer or not.
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if ( std::strcmp(buffer, "Integer") != 0)
core_io_error_handler("BigInt::read_from_file()","type name expected.");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read bigint
read_base_number(in, z, length, maxLength);
}
void writeToFile(const BigInt& z, std::ostream& out, int base, int charsPerLine) {
BigInt c = abs(z);
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name of big number and length
//out << "# This is an experimental big number format.\n";
out << "Integer " << length << "\n";
// if bigint is negative, then write an sign '-'.
if ( sign(z) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << "\n";
delete[] buffer;
}
void readFromFile(BigFloat& bf, std::istream& in, long maxLength) {
char *buffer;
long length;
long exponent;
BigInt mantissa;
// check type name whether it is Float
buffer = new char[6];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "Float") != 0)
core_io_error_handler("BigFloat::read_from_file()", "type name expected");
delete[] buffer;
// read base (default is 16384)
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "(16384)") != 0)
core_io_error_handler("BigFloat::read_from_file()", "base expected");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read exponent
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
exponent = std::atol(buffer);
delete[] buffer;
// read mantissa
read_base_number(in, mantissa, length, maxLength);
// construct BigFloat
bf = BigFloat(mantissa, 0, exponent);
}
void writeToFile(const BigFloat& bf, std::ostream& out, int base, int charsPerLine) {
BigInt c(CORE::abs(bf.m()));
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name, base, length
//out << "# This is an experimental Big Float format." << std::endl;
out << "Float (16384) " << length << std::endl;
// write exponent
out << bf.exp() << std::endl;
// write mantissa
if ( CORE::sign(bf.m()) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
/* Underconstruction ----
void BigFloat::read_from_file2(std::istream& in, long maxLength) {
long length = 1024;
char *buffer;
// check type name whether it is Float
buffer = new char[7];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "NFloat") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "type name expected");
delete[] buffer;
// read base (default is 16)
buffer = new char[5];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "(16)") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "base expected");
delete[] buffer;
// read length field
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
// get the length field if it is not null.
if (buffer[0] != '\0') {
length = atol(buffer);
if (maxLength > 0 && length >= maxLength)
length = maxLength;
}
delete[] buffer;
// read exponent
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
long exp16 = atol(buffer);
delete[] buffer;
// read mantissa
buffer = new char[length+2];
//BigInt::read_base_number(in, buffer, length);
BigInt m16(buffer);
delete[] buffer;
// convert to base CHUNK_BIT
exp16 = exp16 - length + 1;
if ( m16.is_negative() )
exp16 ++;
long tmp_exp = exp16 * 4;
long q = tmp_exp / CHUNK_BIT;
long r = tmp_exp % CHUNK_BIT;
if ( r < 0 ) {
r += CHUNK_BIT;
q --;
}
BigInt mantissa = m16 << r;
long exponent = q;
// construct BigFloat
if (--rep->refCount == 0)
delete rep;
rep = new BigFloatRep(mantissa, 0, exponent);
rep->refCount++;
}
// write normal float
// now it assumed to write in hex base, i.e. B=2^4=16
// (note: our default base B=2^(CHUNK_BIT)=2^14=16384
void BigFloat::write_to_file2(std::ostream& out, int base, int charsPerLine) {
// convert to base 16.
long new_base = 4; // 2^4 = 16
long tmp_exp = (rep->exp) * CHUNK_BIT;
long q = tmp_exp / new_base;
long r = tmp_exp % new_base;
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
if ( r < 0 ) {
r += new_base;
q--;
}
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
BigInt m16 = (rep->m) << r;
int size = mpz_sizeinbase(m16.I, base) + 2;
std::cout << "size=" << size << std::endl;
char* buffer = new char[size];
int length = bigint_to_string(m16, buffer, base);
std::cout << "length=" << length << std::endl;
long exp16 = q + length - 1;
if ( m16.is_negative() )
exp16 --;
// write type name, base, length
out << "# This is an experimental Big Float format." << std::endl;
out << "NFloat (16) " << length << std::endl;
// write exponent
out << exp16 << std::endl;
// write mantissa
if ( m16.is_negative() ) {
out << '-';
buffer ++;
}
BigInt::write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
*/
} //namespace CORE
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/CoreIO_impl.h>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -12,257 +12,9 @@
* $Id$
***************************************************************************/
/* Auxiliary functions for C++-style input of GMP types.
Copyright 2001 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/Gmp.h>
#include <cctype>
#include <iostream>
#include <string>
#include <cstdio>
#include <CGAL/CORE/Gmp_impl.h>
using namespace std;
namespace CORE {
int
__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
{
int base;
zero = showbase = false;
switch (i.flags() & ios::basefield)
{
case ios::dec:
base = 10;
break;
case ios::hex:
base = 16;
break;
case ios::oct:
base = 8;
break;
default:
showbase = true; // look for initial "0" or "0x" or "0X"
if (c == '0')
{
if (! i.get(c))
c = 0; // reset or we might loop indefinitely
if (c == 'x' || c == 'X')
{
base = 16;
i.get(c);
}
else
{
base = 8;
zero = true; // if no other digit is read, the "0" counts
}
}
else
base = 10;
break;
}
return base;
}
void
__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
{
switch (base)
{
case 10:
while (isdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 8:
while (isdigit(c) && c != '8' && c != '9')
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 16:
while (isxdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
}
}
istream &
//operator>> (istream &i, mpz_ptr z)
io_read (istream &i, mpz_ptr z)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-') // mpz_set_str doesn't accept '+'
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the number
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && (ok || zero)) // stopped just before eof
i.clear();
if (ok)
mpz_set_str(z, s.c_str(), base); // extract the number
else if (zero)
mpz_set_ui(z, 0);
else
i.setstate(ios::failbit); // read failed
return i;
}
istream &
//operator>> (istream &i, mpq_ptr q)
io_read (istream &i, mpq_ptr q)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-')
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the numerator
if (! ok && zero) // the only digit read was "0"
{
base = 10;
s += '0';
ok = true;
}
if (i.flags() & ios::skipws)
while (isspace(c) && i.get(c)) // skip whitespace
;
if (c == '/') // there's a denominator
{
bool zero2 = false;
int base2 = base;
s += '/';
ok = false; // denominator is mandatory
i.get(c);
while (isspace(c) && i.get(c)) // skip whitespace
;
if (showbase) // check base of denominator
base2 = __gmp_istream_set_base(i, c, zero2, showbase);
if (base2 == base || base2 == 10) // read the denominator
__gmp_istream_set_digits(s, i, c, ok, base);
if (! ok && zero2) // the only digit read was "0"
{ // denominator is 0, but that's your business
s += '0';
ok = true;
}
}
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && ok) // stopped just before eof
i.clear();
if (ok)
mpq_set_str(q, s.c_str(), base); // extract the number
else
i.setstate(ios::failbit); // read failed
return i;
}
ostream&
//operator<< (ostream &o, mpz_srcptr z)
io_write (ostream &o, mpz_srcptr z)
{
char *str = new char [mpz_sizeinbase(z,10) + 2];
str = mpz_get_str(str, 10, z);
o << str ;
delete[] str;
return o;
}
ostream&
//operator<< (ostream &o, mpq_srcptr q)
io_write (ostream &o, mpq_srcptr q)
{
// size according to GMP documentation
char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) +
mpz_sizeinbase (mpq_denref(q), 10) + 3];
str = mpq_get_str(str, 10, q);
o << str ;
delete[] str;
return o;
}
} //namespace CORE
#endif

View File

@ -35,242 +35,9 @@
* $Id$
***************************************************************************/
#include <ctype.h>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/Real.h>
#include <CGAL/CORE/Real_impl.h>
namespace CORE {
const Real& Real::getZero() {
static Real Zero(0);
return Zero;
}
BigInt floor(const Real& r, Real &sub) {
BigInt f = r.approx(CORE_INFTY, 2).BigIntValue();
sub = r-f;
// Adjustment
if (sub<0)
++sub, --f;
if (sub>=1)
--sub, ++f;
assert(sub >=0 && sub<1);
return f;
}
// pow(r,n) and power(r, n) are the same function
//
Real pow(const Real& r, unsigned long n) {
if (n == 0)
return Real(1);
else if (n == 1)
return r;
else {
Real x = r;
while ((n % 2) == 0) { // n is even
x *= x;
n >>= 1;
}
Real u = x;
while (true) {
n >>= 1;
if (n == 0)
return u;
x *= x;
if ((n % 2) == 1) // n is odd
u *= x;
}
//return u; // unreachable
}
}//pow
extern BigInt FiveTo(unsigned long exp);
// Construct Real from String
// Note:
// -- Zilin Du: 06/03/2003
// -- Original it is the code for Real's constructor for "const char*".
// I change it to a function so that two constrcutors can share the code.
// now it is private and no default value.
//
// --Default value of the argument "prec" is defInputDigits
// --If prec is CORE_posInfty, then the input is
// read in exactly. Otherwise, we convert to a RealBigFloat
// with absolute error at most 10^{-prec}
// Constructor Real( char *str, extLong& prec)
// is very similar to
// BigFloatRep::fromString( char *str, extLong& prec);
// Differences:
// In BigFloat(str, prec), the value of prec cannot be infinity, and
// it defaults to defBigFloatInputDigits;
// In Real(str, prec), the value of prec is allowed to be infinity, and
// it defaults to defInputDigits.
//
// Why do we have the two versions? It allows us to use the BigFloat class
// directly, without relying on Real class.
void Real::constructFromString(const char *str, const extLong& prec )
// NOTE: prec defaults to defInputDigits (see Real.h)
{
// 8/8/01, Chee and Zilin: add a new rational string format:
// this format is indicated by the presence of a slash "/"
// Moreover, the value of prec is ignored (basically
// assumed to be infinity).
if (std::strchr(str, '/') != NULL) { // this is a rational number
rep = new RealBigRat(BigRat(str));
return;
}
const char *e = std::strchr(str, 'e');
int dot = 0;
long e10 = 0;
if (e != NULL)
e10 = std::atol(e+1); // e10 is decimal precision of the input string
// i.e., input is A/10^{e10}.
else {
e = str + std::strlen(str);
#ifdef CORE_DEBUG
assert(*e == '\0');
#endif
}
const char *p = str;
if (*p == '-' || *p == '+')
p++;
BigInt m(0);
for (; p < e; p++) {
if (*p == '.') {
dot = 1;
continue;
}
m = m * 10 + (*p - '0');
if (dot)
e10--;
}
long t = (e10 < 0) ? -e10 : e10;
BigInt one(1);
BigInt ten = FiveTo(t) * (one << static_cast<unsigned long>(t));
if (*str == '-')
m = -m;
if (e10 >= 0) {
// convert exactly from integer numbers
m *= ten;
rep = new RealBigInt(m);
} else { // e10 < 0, fractional numbers
// HERE IS WHERE WE USE THE SYSTEM CONSTANT
// defInputDigits
// Note: defInputDigits should be at least log_2(10).
// We default defInputDigits to 4.
//std::cout << "(m,ten)=" << m << "," << ten << std::endl;
BigRat r(m, ten);
if (prec.isInfty()) { // convert exactly! to a big rational
rep = new RealBigRat(r);
} else {
// convert approximately, to a BigFloat within the
// specified precision:
// BigFloat bf(r, CORE_posInfty, prec * lgTenM) ;
BigFloat bf(r, CORE_posInfty, prec * 4) ;
rep = new RealBigFloat(bf);
}
}
}// Real(str, prec)
// The operator >>(i,x) calls the constructor Real(char*)
std::istream& operator >>(std::istream& i, Real& x) {
int size = 20;
char *str = new char[size];
char *p = str;
char c;
int d = 0, e = 0, s = 0;
// int done = 0;
// Chen Li: fixed a bug, the original statement is
// for (i.get(c); c == ' '; i.get(c));
// use isspace instead of testing c == ' ', since it must also
// skip tab, catridge/return, etc.
// Change to:
// int status;
do {
i.get(c);
} while (!i.eof() && isspace(c)); /* loop if met end-of-file, or
char read in is white-space. */
// Chen Li,
// original "if (c == EOF) ..." is unsafe since c is of char type and
// EOF is of int tyep with a negative value -1
if (i.eof()) {
i.clear(std::ios::eofbit | std::ios::failbit);
delete [] str;
return i;
}
// the current content in "c" should be the first non-whitespace char
if (c == '-' || c == '+') {
*p++ = c;
i.get(c);
}
for (; isdigit(c) || (!d && c=='.') ||
(!e && c=='e') || (!s && (c=='-' || c=='+')); i.get(c)) {
if (!i) break;
if (!e && (c == '-' || c == '+'))
break;
// Chen Li: put one more rule to prohibite input like
// xxxx.xxxe+xxx.xxx:
if (e && (c == '.'))
break;
if (p - str == size) {
char *t = str;
str = new char[size*2];
std::memcpy(str, t, size);
delete [] t;
p = str + size;
size *= 2;
}
#ifdef CORE_DEBUG
assert((p-str) < size);
#endif
*p++ = c;
if (c == '.')
d = 1;
// Chen Li: fix a bug -- the sign of exponent can not happen before
// the character "e" appears! It must follow the "e' actually.
// if (e || c == '-' || c == '+') s = 1;
if (e)
s = 1;
if (c == 'e')
e = 1;
}
if (!i && !i.eof()) {
delete [] str;
return i;
}
// chenli: make sure that the p is still in the range
if (p - str >= size) {
int len = p - str;
char *t = str;
str = new char[len + 1];
std::memcpy(str, t, len);
delete [] t;
p = str + len;
}
#ifdef CORE_DEBUG
assert(p - str < size);
#endif
*p = '\0';
i.putback(c);
i.clear();
// old: x = Real(str, i.precision()); // use precision of input stream.
x = Real(str); // default precision = defInputDigits
delete [] str;
return i;
}//operator >> (std::istream&, Real&)
} //namespace CORE

View File

@ -39,157 +39,9 @@
* $Id$
***************************************************************************/
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/extLong.h>
#include <CGAL/CORE/extLong_impl.h>
namespace CORE {
const extLong& extLong::getNaNLong() {
static extLong NaNLong(true);
return NaNLong;
}
const extLong& extLong::getPosInfty() {
static extLong posInfty(EXTLONG_MAX);
return posInfty;
}
const extLong& extLong::getNegInfty() {
static extLong negInfty(EXTLONG_MIN);
return negInfty;
}
void extLong::add(extLong& z, long x, long y) {
if (x > 0 && y > 0 && x >= EXTLONG_MAX - y) {
z.val = EXTLONG_MAX;
z.flag = 1;
} else if (x < 0 && y < 0 && x <= EXTLONG_MIN - y) {
z.val = EXTLONG_MIN;
z.flag = -1;
} else {
z.val = x + y;
z.flag = 0;
}
}
// arithmetic and assignment operators
extLong& extLong::operator+= (const extLong& y) {
if (flag == 2 || y.flag == 2 || (flag * y.flag < 0)) {
#ifdef CORE_DEBUG
if (flag * y.flag < 0) //want a message at the first creation of NaN
core_error("extLong NaN Error in addition.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if (flag == 1 || y.flag == 1) { // one of them is +Inf
*this = CORE_posInfty;
} else if (flag == -1 || y.flag == -1) { // one of them is -Inf
*this = CORE_negInfty;
} else { // x and y are normal now
add(*this, val, y.val);
}
return *this;
}
extLong& extLong::operator-= (const extLong& y) {
if (flag == 2 || y.flag == 2 || (flag * y.flag > 0)) {
#ifdef CORE_DEBUG
if (flag * y.flag > 0) //want a message at the first creation of NaN
core_error("extLong NaN Error in subtraction.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if (flag == 1 || y.flag == -1) {
*this = CORE_posInfty;
} else if (flag == -1 || y.flag == 1) {
*this = CORE_negInfty;
} else {
add(*this, val, -y.val);
}
return *this;
}
extLong& extLong::operator*= (const extLong& y) {
if (flag == 2 || y.flag == 2) {
*this = CORE_NaNLong;
} else if ((flag != 0) || (y.flag != 0)) {
if (sign() * y.sign() > 0)
*this = CORE_posInfty;
else
*this = CORE_negInfty;
} else { // flag == 0 and y.flag == 0
double d = double(val) * double(y.val);
long p = val * y.val;
if (std::fabs(d - p) <= std::fabs(d) * relEps) {
val = p;
flag = 0;
} else if (d > EXTLONG_MAX) {
*this = CORE_posInfty;
} else if (d < EXTLONG_MIN) {
*this = CORE_negInfty;
} else {
#ifdef CORE_DEBUG
core_error("extLong NaN Error in multiplication.",__FILE__,__LINE__,false);
#endif
*this = CORE_NaNLong;
}
}
return *this;
}
extLong& extLong::operator/= (const extLong& y) {
if (flag==2 || y.flag==2 || ((flag != 0) && (y.flag != 0)) || (y.val == 0)) {
#ifdef CORE_DEBUG
if (y.val == 0)
core_error("extLong NaN Error, Divide by Zero.", __FILE__, __LINE__, false);
else if ((flag !=0) && (y.flag !=0))
core_error("extLong NaN Error, +/-Inf/Inf.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if ((flag != 0) || (y.flag != 0)) { // y.flag == 0 now and y != 0
if (sign() * y.sign() > 0)
*this = CORE_posInfty;
else
*this = CORE_negInfty;
} else { // flag == 0 and y.flag == 0
val /= y.val; // no overflow in divisions
flag = 0;
}
return *this;
}
// unary minus
extLong extLong::operator- () const {
if (flag == 0)
return extLong(-val);
else if (flag == 1)
return CORE_negInfty;
else if (flag == -1)
return CORE_posInfty;
else // NaN
return CORE_NaNLong;
}
// sign
// You should check "flag" before calling this, otherwise
// you cannot interprete the returned value!
int extLong::sign() const {
if (flag == 2)
core_error("NaN Sign can not be determined!", __FILE__, __LINE__, false);
return ((val == 0) ? 0 : ((val > 0) ? 1 : -1));
}
// stream operators
std::ostream& operator<< (std::ostream& o, const extLong& x) {
if (x.flag == 1)
o << " infty ";
else if (x.flag == - 1)
o << " tiny ";
else if (x.flag == 2)
o << " NaN ";
else
o << x.val;
return o;
}
} //namespace CORE

View File

@ -251,7 +251,7 @@ namespace internal{
CORE::BigFloat
inline
round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){
round(const CORE::BigFloat& x, long rel_prec = CORE::get_static_defRelPrec().toLong() ){
CGAL_postcondition(rel_prec >= 0);
// since there is not rel prec defined if Zero_in(x)
@ -344,9 +344,9 @@ public:
typedef long result_type;
long operator() ( long prec ) const {
long result = ::CORE::defRelPrec.toLong();
::CORE::defRelPrec = prec;
::CORE::defBFdivRelPrec = prec;
long result = ::CORE::get_static_defRelPrec().toLong();
::CORE::get_static_defRelPrec() = prec;
::CORE::get_static_defBFdivRelPrec() = prec;
return result;
}
};
@ -356,7 +356,7 @@ public:
typedef long result_type;
long operator() () const {
return ::CORE::defRelPrec.toLong();
return ::CORE::get_static_defRelPrec().toLong();
}
};
};
@ -378,17 +378,19 @@ template <> class Algebraic_structure_traits< CORE::BigFloat >
: public std::unary_function< Type, Type > {
public:
Type operator()( const Type& x ) const {
// What I want is a sqrt computed with ::CORE::defRelPrec bits.
// What I want is a sqrt computed with
// ::CORE::get_static_defRelPrec() bits.
// And not ::CORE::defBFsqrtAbsPrec as CORE does.
CGAL_precondition(::CORE::defRelPrec.toLong() > 0);
CGAL_precondition(::CORE::get_static_defRelPrec().toLong() > 0);
CGAL_precondition(x > 0);
Type a = CGAL::internal::round(x, ::CORE::defRelPrec.toLong()*2);
Type a = CGAL::internal::round(
x, ::CORE::get_static_defRelPrec().toLong()*2);
CGAL_postcondition(a > 0);
Type tmp1 =
CORE::BigFloat(a.m(),0,0).sqrt(::CORE::defRelPrec.toLong());
Type tmp1 = CORE::BigFloat(
a.m(),0,0).sqrt(::CORE::get_static_defRelPrec().toLong());
Type err =
Type(0,long(std::sqrt(double(a.err()))),0)
* CORE::BigFloat::exp2(a.exp()*7);

View File

@ -84,7 +84,7 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigInt>{
Type operator()(const CORE::BigFloat& x) const { return x;}
Type operator()(const ::CORE::BigInt x) const {
CORE::BigFloat result;
result.approx(x,CORE::defRelPrec.toLong(),LONG_MAX);
result.approx(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX);
// Do not use MakeFloorExact as it changes the Bigfloat
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
@ -104,7 +104,7 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigRat>{
Type operator()(const CORE::BigFloat& x) const { return x;}
Type operator()(const ::CORE::BigRat x) const {
CORE::BigFloat result(x,CORE::defRelPrec.toLong(),LONG_MAX);
CORE::BigFloat result(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX);
// Do not use MakeFloorExact as it changes the Bigfloat
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
@ -123,7 +123,7 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::Expr>{
typedef Type result_type;
Type operator()(const CORE::BigFloat& x) const { return x;}
Type operator()(const ::CORE::Expr x) const {
CORE::BigFloat result(x, CORE::defRelPrec.toLong(),LONG_MAX);
CORE::BigFloat result(x, CORE::get_static_defRelPrec().toLong(),LONG_MAX);
// Do not use MakeFloorExact as it changes the Bigfloat
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );

View File

@ -606,64 +606,6 @@ protected:
TLS_thread_uint_ids m_tls_thread_ids;
};
//*****************************************************************************
// class Spatial_lock_grid_3<Tag_non_blocking_with_mutexes>
// Note: undocumented, for testing only...
//*****************************************************************************
template <>
class Spatial_lock_grid_3<Tag_non_blocking_with_mutexes>
: public Spatial_lock_grid_base_3<
Spatial_lock_grid_3<Tag_non_blocking_with_mutexes> >
{
typedef Spatial_lock_grid_base_3<
Spatial_lock_grid_3<Tag_non_blocking_with_mutexes> > Base;
public:
// Constructors
Spatial_lock_grid_3(const Bbox_3 &bbox, int num_grid_cells_per_axis)
: Base(bbox, num_grid_cells_per_axis)
{
int num_cells =
num_grid_cells_per_axis*num_grid_cells_per_axis*num_grid_cells_per_axis;
m_grid.resize(num_cells);
}
/// Destructor
~Spatial_lock_grid_3()
{
}
bool is_cell_locked_impl(int cell_index)
{
bool locked = m_grid[cell_index].try_lock();
if (locked)
m_grid[cell_index].unlock();
return !locked;
}
template <bool no_spin>
bool try_lock_cell_impl(int cell_index)
{
bool success = m_grid[cell_index].try_lock();
if (success)
{
get_thread_local_grid()[cell_index] = true;
m_tls_locked_cells.local().push_back(cell_index);
}
return success;
}
void unlock_cell_impl(int cell_index)
{
m_grid[cell_index].unlock();
}
protected:
std::vector<tbb::recursive_mutex> m_grid;
};
} //namespace CGAL
#else // !CGAL_LINKED_WITH_TBB