mirror of https://github.com/CGAL/cgal
Header-only CGAL_Core
This commit is contained in:
parent
3915c89c17
commit
93a007616a
|
|
@ -37,6 +37,13 @@
|
||||||
|
|
||||||
#include <CGAL/CORE/BigFloatRep.h>
|
#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 {
|
namespace CORE {
|
||||||
|
|
||||||
class Expr;
|
class Expr;
|
||||||
|
|
@ -83,8 +90,8 @@ public:
|
||||||
BigFloat(const BigInt& I)
|
BigFloat(const BigInt& I)
|
||||||
: RCBigFloat(new BigFloatRep(I)) {}
|
: RCBigFloat(new BigFloatRep(I)) {}
|
||||||
/// constructor for <tt>BigRat</tt>
|
/// constructor for <tt>BigRat</tt>
|
||||||
BigFloat(const BigRat& R, const extLong& r = defRelPrec,
|
BigFloat(const BigRat& R, const extLong& r = get_static_defRelPrec(),
|
||||||
const extLong& a = defAbsPrec)
|
const extLong& a = get_static_defAbsPrec())
|
||||||
: RCBigFloat(new BigFloatRep()) {
|
: RCBigFloat(new BigFloatRep()) {
|
||||||
rep->approx(R, r, a);
|
rep->approx(R, r, a);
|
||||||
}
|
}
|
||||||
|
|
@ -93,8 +100,8 @@ public:
|
||||||
// know about Expr, but BigFloat has a special role in our system!
|
// know about Expr, but BigFloat has a special role in our system!
|
||||||
// ===============================
|
// ===============================
|
||||||
/// constructor for <tt>Expr</tt>
|
/// constructor for <tt>Expr</tt>
|
||||||
explicit BigFloat(const Expr& E, const extLong& r = defRelPrec,
|
explicit BigFloat(const Expr& E, const extLong& r = get_static_defRelPrec(),
|
||||||
const extLong& a = defAbsPrec);
|
const extLong& a = get_static_defAbsPrec());
|
||||||
|
|
||||||
//Dummy
|
//Dummy
|
||||||
explicit BigFloat(const BigFloat& E, const extLong& ,
|
explicit BigFloat(const BigFloat& E, const extLong& ,
|
||||||
|
|
@ -161,7 +168,7 @@ public:
|
||||||
/// operator/=
|
/// operator/=
|
||||||
BigFloat& operator/= (const BigFloat& x) {
|
BigFloat& operator/= (const BigFloat& x) {
|
||||||
BigFloat z;
|
BigFloat z;
|
||||||
z.rep->div(*rep, *x.rep, defBFdivRelPrec);
|
z.rep->div(*rep, *x.rep, get_static_defBFdivRelPrec());
|
||||||
*this = z;
|
*this = z;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -182,11 +189,11 @@ public:
|
||||||
/// \name String Conversion Functions
|
/// \name String Conversion Functions
|
||||||
//@{
|
//@{
|
||||||
/// set value from <tt>const char*</tt> (base = 10)
|
/// 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);
|
rep->fromString(s, p);
|
||||||
}
|
}
|
||||||
/// convert to <tt>std::string</tt> (base = 10)
|
/// 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);
|
return rep->toString(prec, sci);
|
||||||
}
|
}
|
||||||
std::string str() const {
|
std::string str() const {
|
||||||
|
|
@ -435,7 +442,7 @@ inline BigFloat operator* (const BigFloat& x, const BigFloat& y) {
|
||||||
/// operator/
|
/// operator/
|
||||||
inline BigFloat operator/ (const BigFloat& x, const BigFloat& y) {
|
inline BigFloat operator/ (const BigFloat& x, const BigFloat& y) {
|
||||||
BigFloat z;
|
BigFloat z;
|
||||||
z.getRep().div(x.getRep(),y.getRep(),defBFdivRelPrec);
|
z.getRep().div(x.getRep(),y.getRep(),get_static_defBFdivRelPrec());
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -490,12 +497,12 @@ inline BigFloat power(const BigFloat& x, unsigned long p) {
|
||||||
/// The argument x is an initial approximation.
|
/// The argument x is an initial approximation.
|
||||||
BigFloat root(const BigFloat&, unsigned long k, const extLong&, const BigFloat&);
|
BigFloat root(const BigFloat&, unsigned long k, const extLong&, const BigFloat&);
|
||||||
inline BigFloat root(const BigFloat& x, unsigned long k) {
|
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:
|
/// sqrt to defAbsPrec:
|
||||||
inline BigFloat sqrt(const BigFloat& x) {
|
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
|
/// 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();
|
*this = f.BigRatValue();
|
||||||
}
|
}
|
||||||
} //namespace CORE
|
} //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_
|
#endif // _CORE_BIGFLOAT_H_
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,13 @@
|
||||||
#include <CGAL/CORE/CoreDefs.h>
|
#include <CGAL/CORE/CoreDefs.h>
|
||||||
#include <CGAL/CORE/extLong.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 {
|
namespace CORE {
|
||||||
|
|
||||||
// forward reference
|
// forward reference
|
||||||
|
|
@ -144,11 +151,11 @@ private:
|
||||||
// conversion
|
// conversion
|
||||||
|
|
||||||
// toString() Joaquin Grech 31/5/2003
|
// 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;
|
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;
|
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
|
void dump() const; //inline
|
||||||
long adjustE(long E, BigInt M, long e) const;
|
long adjustE(long E, BigInt M, long e) const;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -39,6 +39,13 @@
|
||||||
#include <CGAL/CORE/MemoryPool.h>
|
#include <CGAL/CORE/MemoryPool.h>
|
||||||
#include <string>
|
#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 {
|
namespace CORE {
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -559,4 +566,9 @@ inline BigInt randomize(const BigInt& a) {
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
} //namespace CORE
|
} //namespace CORE
|
||||||
|
|
||||||
|
#ifdef CGAL_HEADER_ONLY
|
||||||
|
//#include <CGAL/CORE/CoreIO_impl.h>
|
||||||
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#endif // _CORE_BIGINT_H_
|
#endif // _CORE_BIGINT_H_
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,13 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "CGAL/CORE/Impl.h"
|
#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 {
|
namespace CORE {
|
||||||
|
|
||||||
#ifndef LONG_BIT // such as in Linux
|
#ifndef LONG_BIT // such as in Linux
|
||||||
|
|
@ -181,4 +188,9 @@ inline void core_debug(std::string msg){
|
||||||
|
|
||||||
|
|
||||||
} //namespace CORE
|
} //namespace CORE
|
||||||
|
|
||||||
|
#ifdef CGAL_HEADER_ONLY
|
||||||
|
#include <CGAL/CORE/CoreAux_impl.h>
|
||||||
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#endif // _CORE_COREAUX_H_
|
#endif // _CORE_COREAUX_H_
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -40,6 +40,33 @@
|
||||||
|
|
||||||
#include <CGAL/CORE/extLong.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
|
||||||
|
|
||||||
|
#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 {
|
namespace CORE {
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
@ -60,34 +87,34 @@ namespace CORE {
|
||||||
/** The normal behavior is to abort when an invalid expression
|
/** The normal behavior is to abort when an invalid expression
|
||||||
* is constructed. This flag can be used to turn off this abort.
|
* is constructed. This flag can be used to turn off this abort.
|
||||||
* In any case, an error message will be printed */
|
* 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
|
/// Invalid Flag -- initiallly value is non-negative
|
||||||
/** If the Abort Flag is false, then the Invalid flag will be set to
|
/** If the Abort Flag is false, then the Invalid flag will be set to
|
||||||
* a negative value whenever an invalid expression is constructed.
|
* a negative value whenever an invalid expression is constructed.
|
||||||
* It is the user's responsibility to check this flag and to make
|
* It is the user's responsibility to check this flag and to make
|
||||||
* it non-negative again. */
|
* it non-negative again. */
|
||||||
CGAL_CORE_EXPORT extern int InvalidFlag;
|
CGAL_GLOBAL_STATE_VAR(int, InvalidFlag, 0)
|
||||||
|
|
||||||
/// Escape Precision in bits
|
/// Escape Precision in bits
|
||||||
CGAL_CORE_EXPORT extern extLong EscapePrec;
|
CGAL_GLOBAL_STATE_VAR(extLong, EscapePrec, CORE_posInfty)
|
||||||
|
|
||||||
/// current ur when EscapePrec triggered
|
/// current ur when EscapePrec triggered
|
||||||
/** this flag becomes negative when default EscapePrec is applied */
|
/** 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
|
/// Escape Precision Warning Flag
|
||||||
/** this flag is true by default, and will cause a warning to be printed
|
/** this flag is true by default, and will cause a warning to be printed
|
||||||
when EscapePrec is reached */
|
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
|
// These following two values determine the precision of computing
|
||||||
// approximations in Expr.
|
// approximations in Expr.
|
||||||
|
|
||||||
/// default Relative Precision in bits
|
/// default Relative Precision in bits
|
||||||
CGAL_CORE_EXPORT extern extLong defRelPrec;
|
CGAL_GLOBAL_STATE_VAR(extLong, defRelPrec, 60)
|
||||||
/// default Absolute Precision in bits
|
/// 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.
|
/// default # of decimal digits for conversion from a BF to string.
|
||||||
/** This value cannot be CORE_INFTY.
|
/** 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"
|
"controls the printout precision of std::cout for BigFloat"
|
||||||
Perhaps, we should merge defOutputDigits and defBigFloatOutputDigits?
|
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
|
/// default input precision in digits for converting a string to a Real or Expr
|
||||||
/** This value can be CORE_INFTY */
|
/** 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
|
/// controls the printout precision of std::cout for Real and Expr
|
||||||
/** This value cannot be CORE_INFTY
|
/** This value cannot be CORE_INFTY
|
||||||
See also defBigFloatOutputDigits.
|
See also defBigFloatOutputDigits.
|
||||||
(it really should be an int, as in std::cout.setprecision(int)). */
|
(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
|
/// default input precision in digits for converting a string to a BigFloat
|
||||||
/** This value cannot be CORE_INFTY. */
|
/** This value cannot be CORE_INFTY. */
|
||||||
CGAL_CORE_EXPORT extern long defBigFloatInputDigits;
|
CGAL_GLOBAL_STATE_VAR(long, defBigFloatInputDigits, 16)
|
||||||
|
|
||||||
/// default BigFloat Division Relative Precision
|
/// default BigFloat Division Relative Precision
|
||||||
CGAL_CORE_EXPORT extern extLong defBFdivRelPrec;
|
CGAL_GLOBAL_STATE_VAR(extLong, defBFdivRelPrec, 54)
|
||||||
|
|
||||||
/// default BigFloat Sqrt Absolute Precision
|
/// default BigFloat Sqrt Absolute Precision
|
||||||
CGAL_CORE_EXPORT extern extLong defBFsqrtAbsPrec;
|
CGAL_GLOBAL_STATE_VAR(extLong, defBFsqrtAbsPrec, 54)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// Mode parameters: incremental, progressive, filters
|
// Mode parameters: incremental, progressive, filters
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// floating point filter flag
|
/// 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
|
/// if true, evaluation of expressions would be incremental
|
||||||
CGAL_CORE_EXPORT extern bool incrementalEvalFlag;
|
CGAL_GLOBAL_STATE_VAR(bool, incrementalEvalFlag, true)
|
||||||
/// progressive evaluation flag
|
/// progressive evaluation flag
|
||||||
CGAL_CORE_EXPORT extern bool progressiveEvalFlag;
|
CGAL_GLOBAL_STATE_VAR(bool, progressiveEvalFlag, true)
|
||||||
/// rational reduction flag
|
/// rational reduction flag
|
||||||
CGAL_CORE_EXPORT extern bool rationalReduceFlag;
|
CGAL_GLOBAL_STATE_VAR(bool, rationalReduceFlag, false)
|
||||||
/// default initial (bit) precision for AddSub Progressive Evaluation
|
/// 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
|
// 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
|
/** It determines the precision to which an Expr evaluates its
|
||||||
(exact, implicit) constant value. */
|
(exact, implicit) constant value. */
|
||||||
inline void setDefaultPrecision(const extLong &r, const extLong &a) {
|
inline void setDefaultPrecision(const extLong &r, const extLong &a) {
|
||||||
defRelPrec = r;
|
get_static_defRelPrec() = r;
|
||||||
defAbsPrec = a;
|
get_static_defAbsPrec() = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set default relative precision
|
/// set default relative precision
|
||||||
inline extLong setDefaultRelPrecision(const extLong &r) {
|
inline extLong setDefaultRelPrecision(const extLong &r) {
|
||||||
extLong old = defRelPrec;
|
extLong old = get_static_defRelPrec();
|
||||||
defRelPrec = r;
|
get_static_defRelPrec() = r;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set default absolute precision
|
/// set default absolute precision
|
||||||
inline extLong setDefaultAbsPrecision(const extLong &a) {
|
inline extLong setDefaultAbsPrecision(const extLong &a) {
|
||||||
extLong old = defAbsPrec;
|
extLong old = get_static_defAbsPrec();
|
||||||
defAbsPrec = a;
|
get_static_defAbsPrec() = a;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set default input digits (for Expr, Real)
|
/// set default input digits (for Expr, Real)
|
||||||
/** it controls the absolute error */
|
/** it controls the absolute error */
|
||||||
inline extLong setDefaultInputDigits(const extLong &d) {
|
inline extLong setDefaultInputDigits(const extLong &d) {
|
||||||
extLong old = defInputDigits;
|
extLong old = get_static_defInputDigits();
|
||||||
defInputDigits = d;
|
get_static_defInputDigits() = d;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set default output digits (for Expr, Real)
|
/// 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) {
|
std::ostream& o = std::cout) {
|
||||||
long old = defOutputDigits;
|
long old = get_static_defOutputDigits();
|
||||||
defOutputDigits = d;
|
get_static_defOutputDigits() = d;
|
||||||
o.precision(d);
|
o.precision(d);
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set default input digits for BigFloat
|
/// set default input digits for BigFloat
|
||||||
inline long setDefaultBFInputDigits(long d) {
|
inline long setDefaultBFInputDigits(long d) {
|
||||||
long old = defBigFloatInputDigits;
|
long old = get_static_defBigFloatInputDigits();
|
||||||
defBigFloatInputDigits = d;
|
get_static_defBigFloatInputDigits() = d;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set default output digits for BigFloat
|
/// set default output digits for BigFloat
|
||||||
inline long setDefaultBFOutputDigits(long d) {
|
inline long setDefaultBFOutputDigits(long d) {
|
||||||
long old = defBigFloatOutputDigits;
|
long old = get_static_defBigFloatOutputDigits();
|
||||||
defBigFloatOutputDigits = d;
|
get_static_defBigFloatOutputDigits() = d;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// turn floating-point filter on/off
|
/// turn floating-point filter on/off
|
||||||
inline bool setFpFilterFlag(bool f) {
|
inline bool setFpFilterFlag(bool f) {
|
||||||
bool oldf = fpFilterFlag;
|
bool oldf = get_static_fpFilterFlag();
|
||||||
fpFilterFlag = f;
|
get_static_fpFilterFlag() = f;
|
||||||
return oldf;
|
return oldf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// turn incremental evaluation flag on/off
|
/// turn incremental evaluation flag on/off
|
||||||
inline bool setIncrementalEvalFlag(bool f) {
|
inline bool setIncrementalEvalFlag(bool f) {
|
||||||
bool oldf = incrementalEvalFlag;
|
bool oldf = get_static_incrementalEvalFlag();
|
||||||
incrementalEvalFlag = f;
|
get_static_incrementalEvalFlag() = f;
|
||||||
return oldf;
|
return oldf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// turn progressive evaluation flag on/off
|
/// turn progressive evaluation flag on/off
|
||||||
inline bool setProgressiveEvalFlag(bool f) {
|
inline bool setProgressiveEvalFlag(bool f) {
|
||||||
bool oldf = progressiveEvalFlag;
|
bool oldf = get_static_progressiveEvalFlag();
|
||||||
progressiveEvalFlag = f;
|
get_static_progressiveEvalFlag() = f;
|
||||||
return oldf;
|
return oldf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set initial bit precision for progressive evaluation:
|
/// set initial bit precision for progressive evaluation:
|
||||||
inline long setDefInitialProgressivePrec(long n) {
|
inline long setDefInitialProgressivePrec(long n) {
|
||||||
long oldn = defInitialProgressivePrec;
|
long oldn = get_static_defInitialProgressivePrec();
|
||||||
defInitialProgressivePrec = n;
|
get_static_defInitialProgressivePrec() = n;
|
||||||
return oldn;
|
return oldn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// turn rational reduction flag on/off
|
/// turn rational reduction flag on/off
|
||||||
inline bool setRationalReduceFlag(bool f) {
|
inline bool setRationalReduceFlag(bool f) {
|
||||||
bool oldf = rationalReduceFlag;
|
bool oldf = get_static_rationalReduceFlag();
|
||||||
rationalReduceFlag = f;
|
get_static_rationalReduceFlag() = f;
|
||||||
return oldf;
|
return oldf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,9 +261,9 @@ inline bool setRationalReduceFlag(bool f) {
|
||||||
e.g., overriding the default std::cout precision (most systems
|
e.g., overriding the default std::cout precision (most systems
|
||||||
initializes this value to 6) to our own */
|
initializes this value to 6) to our own */
|
||||||
inline void CORE_init(long d) {
|
inline void CORE_init(long d) {
|
||||||
defAbsPrec = CORE_posInfty;
|
get_static_defAbsPrec() = CORE_posInfty;
|
||||||
defOutputDigits = d;
|
get_static_defOutputDigits() = d;
|
||||||
std::setprecision(defOutputDigits);
|
std::setprecision(get_static_defOutputDigits());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// change to scientific output format
|
/// change to scientific output format
|
||||||
|
|
@ -251,4 +277,9 @@ inline void setPositionalFormat(std::ostream& o = std::cout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace CORE
|
} //namespace CORE
|
||||||
|
|
||||||
|
#ifdef CGAL_HEADER_ONLY
|
||||||
|
#include <CGAL/CORE/CoreDefs_impl.h>
|
||||||
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#endif // _CORE_COREDEFS_H_
|
#endif // _CORE_COREDEFS_H_
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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_
|
||||||
|
|
@ -36,11 +36,22 @@
|
||||||
* $Id$
|
* $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_
|
#ifndef _CORE_EXPR_H_
|
||||||
#define _CORE_EXPR_H_
|
#define _CORE_EXPR_H_
|
||||||
|
|
||||||
#include <CGAL/CORE/ExprRep.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 {
|
namespace CORE {
|
||||||
|
|
||||||
/// \class Expr Expr.h
|
/// \class Expr Expr.h
|
||||||
|
|
@ -78,9 +89,9 @@ public:
|
||||||
// (i.e., not infinite and not NaN)
|
// (i.e., not infinite and not NaN)
|
||||||
if (! CGAL_CORE_finite(f)) {
|
if (! CGAL_CORE_finite(f)) {
|
||||||
std::cerr << " ERROR : constructed an invalid float! " << std::endl;
|
std::cerr << " ERROR : constructed an invalid float! " << std::endl;
|
||||||
if (AbortFlag)
|
if (get_static_AbortFlag())
|
||||||
abort();
|
abort();
|
||||||
InvalidFlag = -1;
|
get_static_InvalidFlag() = -1;
|
||||||
}
|
}
|
||||||
rep = new ConstDoubleRep(f);
|
rep = new ConstDoubleRep(f);
|
||||||
}
|
}
|
||||||
|
|
@ -89,9 +100,9 @@ public:
|
||||||
// (i.e., not infinite and not NaN)
|
// (i.e., not infinite and not NaN)
|
||||||
if (! CGAL_CORE_finite(d)) {
|
if (! CGAL_CORE_finite(d)) {
|
||||||
std::cerr << " ERROR : constructed an invalid double! " << std::endl;
|
std::cerr << " ERROR : constructed an invalid double! " << std::endl;
|
||||||
if (AbortFlag)
|
if (get_static_AbortFlag())
|
||||||
abort();
|
abort();
|
||||||
InvalidFlag = -2;
|
get_static_InvalidFlag() = -2;
|
||||||
}
|
}
|
||||||
rep = new ConstDoubleRep(d);
|
rep = new ConstDoubleRep(d);
|
||||||
}
|
}
|
||||||
|
|
@ -111,11 +122,11 @@ public:
|
||||||
* it is generally recommended that the (String) constructor be used in
|
* it is generally recommended that the (String) constructor be used in
|
||||||
* preference to the (double) constructor.
|
* 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))) {}
|
: RCExpr(new ConstRealRep(Real(s, p))) {}
|
||||||
|
|
||||||
/// constructor for <tt>std::string</tt>
|
/// 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))) {}
|
: RCExpr(new ConstRealRep(Real(s, p))) {}
|
||||||
|
|
||||||
/// constructor for <tt>Real</tt>
|
/// constructor for <tt>Real</tt>
|
||||||
|
|
@ -179,9 +190,9 @@ public:
|
||||||
Expr& operator/=(const Expr& e) {
|
Expr& operator/=(const Expr& e) {
|
||||||
if ((e.rep)->getSign() == 0) {
|
if ((e.rep)->getSign() == 0) {
|
||||||
std::cerr << " ERROR : division by zero ! " << std::endl;
|
std::cerr << " ERROR : division by zero ! " << std::endl;
|
||||||
if (AbortFlag)
|
if (get_static_AbortFlag())
|
||||||
abort();
|
abort();
|
||||||
InvalidFlag = -3;
|
get_static_InvalidFlag() = -3;
|
||||||
}
|
}
|
||||||
*this = new DivRep(rep, e.rep);
|
*this = new DivRep(rep, e.rep);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -225,12 +236,12 @@ public:
|
||||||
/// \name String Conversion Functions
|
/// \name String Conversion Functions
|
||||||
//@{
|
//@{
|
||||||
/// set value from <tt>const char*</tt>
|
/// 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);
|
*this = Expr(s, prec);
|
||||||
}
|
}
|
||||||
/// convert to <tt>std::string</tt>
|
/// convert to <tt>std::string</tt>
|
||||||
/** give decimal string representation */
|
/** 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);
|
return rep->toString(prec, sci);
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
@ -282,8 +293,8 @@ public:
|
||||||
/** Here is the definition of what this means:
|
/** Here is the definition of what this means:
|
||||||
If e is the exact value and ee is the approximate value,
|
If e is the exact value and ee is the approximate value,
|
||||||
then |e - ee| <= 2^{-a} or |e - ee| <= 2^{-r} |e|. */
|
then |e - ee| <= 2^{-a} or |e - ee| <= 2^{-r} |e|. */
|
||||||
const Real & approx(const extLong& relPrec = defRelPrec,
|
const Real & approx(const extLong& relPrec = get_static_defRelPrec(),
|
||||||
const extLong& absPrec = defAbsPrec) const {
|
const extLong& absPrec = get_static_defAbsPrec()) const {
|
||||||
return rep->getAppValue(relPrec, absPrec);
|
return rep->getAppValue(relPrec, absPrec);
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
@ -355,7 +366,7 @@ inline std::ostream& operator<<(std::ostream& o, const Expr& e) {
|
||||||
/// I/O Stream operator>>
|
/// I/O Stream operator>>
|
||||||
inline std::istream& operator>>(std::istream& i, Expr& e) {
|
inline std::istream& operator>>(std::istream& i, Expr& e) {
|
||||||
Real rVal;
|
Real rVal;
|
||||||
i >> rVal; // precision is = defInputDigits
|
i >> rVal; // precision is = get_static_defInputDigits()
|
||||||
if (i)
|
if (i)
|
||||||
e = rVal; // only assign when reading is successful.
|
e = rVal; // only assign when reading is successful.
|
||||||
return i;
|
return i;
|
||||||
|
|
@ -382,9 +393,9 @@ inline Expr operator*(const Expr& e1, const Expr& e2) {
|
||||||
inline Expr operator/(const Expr& e1, const Expr& e2) {
|
inline Expr operator/(const Expr& e1, const Expr& e2) {
|
||||||
if (e2.sign() == 0) {
|
if (e2.sign() == 0) {
|
||||||
std::cerr << " ERROR : division by zero ! " << std::endl;
|
std::cerr << " ERROR : division by zero ! " << std::endl;
|
||||||
if (AbortFlag)
|
if (get_static_AbortFlag())
|
||||||
abort();
|
abort();
|
||||||
InvalidFlag = -4;
|
get_static_InvalidFlag() = -4;
|
||||||
}
|
}
|
||||||
return Expr(new DivRep(e1.Rep(), e2.Rep()));
|
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) {
|
inline Expr sqrt(const Expr& e) {
|
||||||
if (e.sign() < 0) {
|
if (e.sign() < 0) {
|
||||||
std::cerr << " ERROR : sqrt of negative value ! " << std::endl;
|
std::cerr << " ERROR : sqrt of negative value ! " << std::endl;
|
||||||
if (AbortFlag)
|
if (get_static_AbortFlag())
|
||||||
abort();
|
abort();
|
||||||
InvalidFlag = -5;
|
get_static_InvalidFlag() = -5;
|
||||||
}
|
}
|
||||||
return Expr(new SqrtRep(e.Rep()));
|
return Expr(new SqrtRep(e.Rep()));
|
||||||
}
|
}
|
||||||
|
|
@ -548,4 +559,9 @@ inline Expr radical(const NT& n, int m) {
|
||||||
#include <CGAL/CORE/poly/Poly.tcc>
|
#include <CGAL/CORE/poly/Poly.tcc>
|
||||||
|
|
||||||
} //namespace CORE
|
} //namespace CORE
|
||||||
|
|
||||||
|
#ifdef CGAL_HEADER_ONLY
|
||||||
|
#include <CGAL/CORE/Expr_impl.h>
|
||||||
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#endif // _CORE_EXPR_H_
|
#endif // _CORE_EXPR_H_
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,16 @@
|
||||||
#include <CGAL/CORE/Filter.h>
|
#include <CGAL/CORE/Filter.h>
|
||||||
#include <CGAL/CORE/poly/Sturm.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 {
|
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
|
// These counters are incremented each time each bound is recognized as equal
|
||||||
// to the best one in computeBound().
|
// to the best one in computeBound().
|
||||||
extern unsigned int BFMSS_counter;
|
extern unsigned int BFMSS_counter;
|
||||||
|
|
@ -189,8 +196,8 @@ public:
|
||||||
/// \name Helper Functions
|
/// \name Helper Functions
|
||||||
//@{
|
//@{
|
||||||
/// Get the approximate value
|
/// Get the approximate value
|
||||||
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = defRelPrec,
|
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = get_static_defRelPrec(),
|
||||||
const extLong& absPrec = defAbsPrec);
|
const extLong& absPrec = get_static_defAbsPrec());
|
||||||
/// Get the sign.
|
/// Get the sign.
|
||||||
int getSign();
|
int getSign();
|
||||||
int getExactSign();
|
int getExactSign();
|
||||||
|
|
@ -389,8 +396,8 @@ public:
|
||||||
BigFloat BigFloatValue();
|
BigFloat BigFloatValue();
|
||||||
/// represent as a string in decimal value
|
/// represent as a string in decimal value
|
||||||
// toString() Joaquin Grech 31/5/2003
|
// toString() Joaquin Grech 31/5/2003
|
||||||
std::string toString(long prec=defOutputDigits, bool sci=false) {
|
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) {
|
||||||
return (getAppValue(defRelPrec, defAbsPrec)).toString(prec,sci);
|
return (getAppValue(get_static_defRelPrec(), get_static_defAbsPrec())).toString(prec,sci);
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
@ -677,7 +684,7 @@ protected:
|
||||||
tc() = ceilLg(ss.seq[0].getTailCoeff());
|
tc() = ceilLg(ss.seq[0].getTailCoeff());
|
||||||
|
|
||||||
// no rational reduction
|
// no rational reduction
|
||||||
if (rationalReduceFlag)
|
if (get_static_rationalReduceFlag())
|
||||||
ratFlag() = -1;
|
ratFlag() = -1;
|
||||||
|
|
||||||
flagsComputed() = true;
|
flagsComputed() = true;
|
||||||
|
|
@ -838,7 +845,12 @@ protected:
|
||||||
/// \brief "functor" class used as parameter to AddSubRep<>
|
/// \brief "functor" class used as parameter to AddSubRep<>
|
||||||
struct Add {
|
struct Add {
|
||||||
/// name
|
/// name
|
||||||
|
#ifndef CGAL_HEADER_ONLY
|
||||||
CGAL_CORE_EXPORT static const char* name;
|
CGAL_CORE_EXPORT static const char* name;
|
||||||
|
#endif
|
||||||
|
static const char* get_name() {
|
||||||
|
return "+";
|
||||||
|
}
|
||||||
|
|
||||||
/// unary operator
|
/// unary operator
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
@ -857,7 +869,12 @@ struct Add {
|
||||||
/// \brief "functor" class used as parameter to AddSubRep<>
|
/// \brief "functor" class used as parameter to AddSubRep<>
|
||||||
struct Sub {
|
struct Sub {
|
||||||
/// name
|
/// name
|
||||||
|
#ifndef CGAL_HEADER_ONLY
|
||||||
CGAL_CORE_EXPORT static const char* name;
|
CGAL_CORE_EXPORT static const char* name;
|
||||||
|
#endif
|
||||||
|
static const char* get_name() {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
|
||||||
/// unary operator
|
/// unary operator
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
@ -895,7 +912,7 @@ protected:
|
||||||
void computeApproxValue(const extLong&, const extLong&);
|
void computeApproxValue(const extLong&, const extLong&);
|
||||||
/// return operator in string
|
/// return operator in string
|
||||||
const std::string op() const {
|
const std::string op() const {
|
||||||
return Operator::name;
|
return Operator::get_name();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static Operator Op;
|
static Operator Op;
|
||||||
|
|
@ -925,7 +942,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
||||||
reduceTo(second);
|
reduceTo(second);
|
||||||
sign() = Op(ss);
|
sign() = Op(ss);
|
||||||
appValue() = Op(appValue());
|
appValue() = Op(appValue());
|
||||||
if (rationalReduceFlag && ratFlag() > 0)
|
if (get_static_rationalReduceFlag() && ratFlag() > 0)
|
||||||
*(ratValue()) = Op(*(ratValue()));
|
*(ratValue()) = Op(*(ratValue()));
|
||||||
return;
|
return;
|
||||||
} else if (ss == 0) { // second operand is zero
|
} else if (ss == 0) { // second operand is zero
|
||||||
|
|
@ -933,7 +950,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// rational node
|
// rational node
|
||||||
if (rationalReduceFlag) {
|
if (get_static_rationalReduceFlag()) {
|
||||||
if (first->ratFlag() > 0 && second->ratFlag() > 0) {
|
if (first->ratFlag() > 0 && second->ratFlag() > 0) {
|
||||||
BigRat val=Op(*(first->ratValue()), *(second->ratValue()));
|
BigRat val=Op(*(first->ratValue()), *(second->ratValue()));
|
||||||
reduceToBigRat(val);
|
reduceToBigRat(val);
|
||||||
|
|
@ -1046,7 +1063,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
||||||
if (lowBound <= EXTLONG_ZERO)
|
if (lowBound <= EXTLONG_ZERO)
|
||||||
lowBound = EXTLONG_ONE;
|
lowBound = EXTLONG_ONE;
|
||||||
|
|
||||||
if (!progressiveEvalFlag) {
|
if (!get_static_progressiveEvalFlag()) {
|
||||||
// convert the absolute error requirement "lowBound" to
|
// convert the absolute error requirement "lowBound" to
|
||||||
// a relative error requirement "ur", s.t.
|
// a relative error requirement "ur", s.t.
|
||||||
// |x|*2^(-ur) <= 2^(-lowBound).
|
// |x|*2^(-ur) <= 2^(-lowBound).
|
||||||
|
|
@ -1085,7 +1102,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
||||||
// larger than lowBound AND the defaultInitialProgressivePrec,
|
// larger than lowBound AND the defaultInitialProgressivePrec,
|
||||||
// so that we do at least one iteration of the for-loop. So:
|
// so that we do at least one iteration of the for-loop. So:
|
||||||
// i is the variable for iteration.
|
// 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;
|
extLong ua = lowBound.asLong() + EXTLONG_ONE;
|
||||||
// NOTE: ua is allowed to be CORE_INFTY
|
// NOTE: ua is allowed to be CORE_INFTY
|
||||||
|
|
||||||
|
|
@ -1096,7 +1113,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
||||||
lMSB() = CORE_negInfty;
|
lMSB() = CORE_negInfty;
|
||||||
sign() = 0;
|
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,
|
// Now we try to determine the real lMSB and sign,
|
||||||
// in case it is not really zero:
|
// 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!
|
break; // assert -- this must happen in the loop if nonzero!
|
||||||
}
|
}
|
||||||
//8/9/01, Chee: implement escape precision here:
|
//8/9/01, Chee: implement escape precision here:
|
||||||
if (i> EscapePrec) {
|
if (i> get_static_EscapePrec()) {
|
||||||
EscapePrecFlag = -i.asLong();//negative means EscapePrec is used
|
get_static_EscapePrecFlag() = -i.asLong();//negative means EscapePrec is used
|
||||||
core_error("Escape precision triggered at",
|
core_error("Escape precision triggered at",
|
||||||
__FILE__, __LINE__, false);
|
__FILE__, __LINE__, false);
|
||||||
if (EscapePrecWarning)
|
if (get_static_EscapePrecWarning())
|
||||||
std::cout<< "Escape Precision triggered at "
|
std::cout<< "Escape Precision triggered at "
|
||||||
<< EscapePrec << " bits" << std::endl;
|
<< get_static_EscapePrec() << " bits" << std::endl;
|
||||||
#ifdef CORE_DEBUG
|
#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;
|
std::cout << "ua =" << ua << ",lowBound=" << lowBound << std::endl;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}// if
|
}// if
|
||||||
}// for (long i=1...)
|
}// for (long i=1...)
|
||||||
|
|
||||||
#ifdef CORE_DEBUG_BOUND
|
#if defined(CORE_DEBUG_BOUND) && !defined(CGAL_HEADER_ONLY)
|
||||||
rootBoundHitCounter++;
|
rootBoundHitCounter++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -42,6 +42,13 @@
|
||||||
#include <CGAL/CORE/Real.h>
|
#include <CGAL/CORE/Real.h>
|
||||||
#include <cmath>
|
#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
|
#if !defined CGAL_CFG_NO_CPP0X_ISFINITE
|
||||||
#define CGAL_CORE_finite(x) std::isfinite(x)
|
#define CGAL_CORE_finite(x) std::isfinite(x)
|
||||||
#elif defined (_MSC_VER) || defined (__MINGW32__) // add support for MinGW
|
#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
|
/// check whether the sign (!) of the filtered value is OK
|
||||||
bool isOK() const {
|
bool isOK() const {
|
||||||
return (fpFilterFlag && // To disable filter
|
return (get_static_fpFilterFlag() && // To disable filter
|
||||||
CGAL_CORE_finite(fpVal) && // Test for infinite and NaNs
|
CGAL_CORE_finite(fpVal) && // Test for infinite and NaNs
|
||||||
(core_abs(fpVal) >= maxAbs*ind*CORE_EPS));
|
(core_abs(fpVal) >= maxAbs*ind*CORE_EPS));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,13 @@
|
||||||
#include <CGAL/CORE/Impl.h>
|
#include <CGAL/CORE/Impl.h>
|
||||||
#include <gmp.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 {
|
namespace CORE {
|
||||||
|
|
||||||
CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpz_srcptr);
|
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);
|
//std::istream& operator>> (std::istream &, mpq_ptr);
|
||||||
|
|
||||||
} //namespace CORE
|
} //namespace CORE
|
||||||
|
|
||||||
|
#ifdef CGAL_HEADER_ONLY
|
||||||
|
#include <CGAL/CORE/Gmp_impl.h>
|
||||||
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#endif // _CORE_GMP_H_
|
#endif // _CORE_GMP_H_
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -39,6 +39,13 @@
|
||||||
#define _CORE_REAL_H_
|
#define _CORE_REAL_H_
|
||||||
#include "RealRep.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 {
|
namespace CORE {
|
||||||
// class Real
|
// class Real
|
||||||
typedef RCImpl<RealRep> RCReal;
|
typedef RCImpl<RealRep> RCReal;
|
||||||
|
|
@ -57,10 +64,10 @@ public:
|
||||||
Real(const BigInt& I) : RCReal(new RealBigInt(I)) {}
|
Real(const BigInt& I) : RCReal(new RealBigInt(I)) {}
|
||||||
Real(const BigRat& R) : RCReal(new RealBigRat(R)) {}
|
Real(const BigRat& R) : RCReal(new RealBigRat(R)) {}
|
||||||
Real(const BigFloat& F) : RCReal(new RealBigFloat(F)) {}
|
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);
|
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);
|
constructFromString(s.c_str(), prec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,12 +141,12 @@ public:
|
||||||
/// \name String Conversion Functions
|
/// \name String Conversion Functions
|
||||||
//@{
|
//@{
|
||||||
/// set value from <tt>const char*</tt>
|
/// 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);
|
*this = Real(s, prec);
|
||||||
}
|
}
|
||||||
/// convert to <tt>std::string</tt>
|
/// convert to <tt>std::string</tt>
|
||||||
/** give decimal string representation */
|
/** 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);
|
return rep->toString(prec, sci);
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
@ -179,7 +186,8 @@ public:
|
||||||
/// \name Aprroximation Function
|
/// \name Aprroximation Function
|
||||||
//@{
|
//@{
|
||||||
/// approximation
|
/// 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);
|
return rep->approx(r, a);
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
@ -395,7 +403,7 @@ inline Real& Real::operator*=(const Real& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline Real& Real::operator/=(const Real& rhs) {
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,7 +421,7 @@ inline Real operator*(const Real& x, const Real& y) {
|
||||||
}
|
}
|
||||||
// operator/
|
// operator/
|
||||||
inline Real operator/(const Real& x, const Real& y) {
|
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
|
// div w/ precision
|
||||||
inline Real Real::div(const Real& x, const extLong& r) const {
|
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
|
/// square root
|
||||||
inline Real sqrt(const Real& x) {
|
inline Real sqrt(const Real& x) {
|
||||||
return x.sqrt(defAbsPrec);
|
return x.sqrt(get_static_defAbsPrec());
|
||||||
}
|
}
|
||||||
|
|
||||||
// class Realbase_for (need defined after Real)
|
// class Realbase_for (need defined after Real)
|
||||||
|
|
@ -493,4 +501,9 @@ inline Real RealLong::operator-() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace CORE
|
} //namespace CORE
|
||||||
|
|
||||||
|
#ifdef CGAL_HEADER_ONLY
|
||||||
|
#include <CGAL/CORE/Real_impl.h>
|
||||||
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#endif // _CORE_REAL_H_
|
#endif // _CORE_REAL_H_
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,13 @@
|
||||||
#include <CGAL/CORE/Impl.h>
|
#include <CGAL/CORE/Impl.h>
|
||||||
#include <CGAL/CORE/CoreAux.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 {
|
namespace CORE {
|
||||||
|
|
||||||
#ifndef LONG_MAX
|
#ifndef LONG_MAX
|
||||||
|
|
@ -294,4 +301,9 @@ inline bool extLong::isNaN() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace CORE
|
} //namespace CORE
|
||||||
|
|
||||||
|
#ifdef CGAL_HEADER_ONLY
|
||||||
|
#include <CGAL/CORE/extLong_impl.h>
|
||||||
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#endif // _CORE_EXTLONG_H_
|
#endif // _CORE_EXTLONG_H_
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,8 @@ public:
|
||||||
/// Polynomial evaluation where the coefficients are approximated first
|
/// Polynomial evaluation where the coefficients are approximated first
|
||||||
/// Returns a BigFloat with error that contains the value
|
/// Returns a BigFloat with error that contains the value
|
||||||
BigFloat evalApprox(const BigFloat& f,
|
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.
|
/// Polynomial evaluation at a BigFloat value.
|
||||||
/// The returned BigFloat (with error) has the exact sign.
|
/// The returned BigFloat (with error) has the exact sign.
|
||||||
/// In particular, if the value is 0, we return 0.
|
/// In particular, if the value is 0, we return 0.
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -33,181 +33,9 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "CGAL/CORE/CoreAux.h"
|
#ifndef CGAL_HEADER_ONLY
|
||||||
#include <gmp.h>
|
|
||||||
|
|
||||||
namespace CORE {
|
#include <CGAL/CORE/CoreAux.h>
|
||||||
|
#include <CGAL/CORE/CoreAux_impl.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
#endif
|
||||||
// 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
|
|
||||||
|
|
|
||||||
|
|
@ -32,124 +32,9 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "CGAL/CORE/CoreDefs.h"
|
#ifndef CGAL_HEADER_ONLY
|
||||||
|
|
||||||
namespace CORE {
|
#include <CGAL/CORE/CoreDefs.h>
|
||||||
|
#include <CGAL/CORE/CoreDefs_impl.h>
|
||||||
// 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
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -29,430 +29,6 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <CGAL/CORE/BigFloatRep.h>
|
#ifndef CGAL_HEADER_ONLY
|
||||||
#include <CGAL/CORE/BigFloat.h>
|
#include <CGAL/CORE/CoreIO_impl.h>
|
||||||
|
#endif
|
||||||
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
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -12,257 +12,9 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/* Auxiliary functions for C++-style input of GMP types.
|
#ifndef CGAL_HEADER_ONLY
|
||||||
|
|
||||||
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. */
|
|
||||||
|
|
||||||
#include <CGAL/CORE/Gmp.h>
|
#include <CGAL/CORE/Gmp.h>
|
||||||
#include <cctype>
|
#include <CGAL/CORE/Gmp_impl.h>
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
using namespace std;
|
#endif
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
||||||
|
|
@ -35,242 +35,9 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <ctype.h>
|
#ifndef CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#include <CGAL/CORE/Real.h>
|
#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
|
#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
|
|
||||||
|
|
|
||||||
|
|
@ -39,157 +39,9 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#include <CGAL/CORE/extLong.h>
|
#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
|
#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
|
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,7 @@ namespace internal{
|
||||||
|
|
||||||
CORE::BigFloat
|
CORE::BigFloat
|
||||||
inline
|
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);
|
CGAL_postcondition(rel_prec >= 0);
|
||||||
|
|
||||||
// since there is not rel prec defined if Zero_in(x)
|
// since there is not rel prec defined if Zero_in(x)
|
||||||
|
|
@ -344,9 +344,9 @@ public:
|
||||||
typedef long result_type;
|
typedef long result_type;
|
||||||
|
|
||||||
long operator() ( long prec ) const {
|
long operator() ( long prec ) const {
|
||||||
long result = ::CORE::defRelPrec.toLong();
|
long result = ::CORE::get_static_defRelPrec().toLong();
|
||||||
::CORE::defRelPrec = prec;
|
::CORE::get_static_defRelPrec() = prec;
|
||||||
::CORE::defBFdivRelPrec = prec;
|
::CORE::get_static_defBFdivRelPrec() = prec;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -356,7 +356,7 @@ public:
|
||||||
typedef long result_type;
|
typedef long result_type;
|
||||||
|
|
||||||
long operator() () const {
|
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 std::unary_function< Type, Type > {
|
||||||
public:
|
public:
|
||||||
Type operator()( const Type& x ) const {
|
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.
|
// 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);
|
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);
|
CGAL_postcondition(a > 0);
|
||||||
|
|
||||||
Type tmp1 =
|
Type tmp1 = CORE::BigFloat(
|
||||||
CORE::BigFloat(a.m(),0,0).sqrt(::CORE::defRelPrec.toLong());
|
a.m(),0,0).sqrt(::CORE::get_static_defRelPrec().toLong());
|
||||||
Type err =
|
Type err =
|
||||||
Type(0,long(std::sqrt(double(a.err()))),0)
|
Type(0,long(std::sqrt(double(a.err()))),0)
|
||||||
* CORE::BigFloat::exp2(a.exp()*7);
|
* CORE::BigFloat::exp2(a.exp()*7);
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigInt>{
|
||||||
Type operator()(const CORE::BigFloat& x) const { return x;}
|
Type operator()(const CORE::BigFloat& x) const { return x;}
|
||||||
Type operator()(const ::CORE::BigInt x) const {
|
Type operator()(const ::CORE::BigInt x) const {
|
||||||
CORE::BigFloat result;
|
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
|
// 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 );
|
||||||
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::BigFloat& x) const { return x;}
|
||||||
Type operator()(const ::CORE::BigRat x) const {
|
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
|
// 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 );
|
||||||
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;
|
typedef Type result_type;
|
||||||
Type operator()(const CORE::BigFloat& x) const { return x;}
|
Type operator()(const CORE::BigFloat& x) const { return x;}
|
||||||
Type operator()(const ::CORE::Expr x) const {
|
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
|
// 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 );
|
||||||
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 );
|
||||||
|
|
|
||||||
|
|
@ -606,64 +606,6 @@ protected:
|
||||||
TLS_thread_uint_ids m_tls_thread_ids;
|
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
|
} //namespace CGAL
|
||||||
|
|
||||||
#else // !CGAL_LINKED_WITH_TBB
|
#else // !CGAL_LINKED_WITH_TBB
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue