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>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
class Expr;
|
||||
|
|
@ -83,8 +90,8 @@ public:
|
|||
BigFloat(const BigInt& I)
|
||||
: RCBigFloat(new BigFloatRep(I)) {}
|
||||
/// constructor for <tt>BigRat</tt>
|
||||
BigFloat(const BigRat& R, const extLong& r = defRelPrec,
|
||||
const extLong& a = defAbsPrec)
|
||||
BigFloat(const BigRat& R, const extLong& r = get_static_defRelPrec(),
|
||||
const extLong& a = get_static_defAbsPrec())
|
||||
: RCBigFloat(new BigFloatRep()) {
|
||||
rep->approx(R, r, a);
|
||||
}
|
||||
|
|
@ -93,8 +100,8 @@ public:
|
|||
// know about Expr, but BigFloat has a special role in our system!
|
||||
// ===============================
|
||||
/// constructor for <tt>Expr</tt>
|
||||
explicit BigFloat(const Expr& E, const extLong& r = defRelPrec,
|
||||
const extLong& a = defAbsPrec);
|
||||
explicit BigFloat(const Expr& E, const extLong& r = get_static_defRelPrec(),
|
||||
const extLong& a = get_static_defAbsPrec());
|
||||
|
||||
//Dummy
|
||||
explicit BigFloat(const BigFloat& E, const extLong& ,
|
||||
|
|
@ -161,7 +168,7 @@ public:
|
|||
/// operator/=
|
||||
BigFloat& operator/= (const BigFloat& x) {
|
||||
BigFloat z;
|
||||
z.rep->div(*rep, *x.rep, defBFdivRelPrec);
|
||||
z.rep->div(*rep, *x.rep, get_static_defBFdivRelPrec());
|
||||
*this = z;
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -182,11 +189,11 @@ public:
|
|||
/// \name String Conversion Functions
|
||||
//@{
|
||||
/// set value from <tt>const char*</tt> (base = 10)
|
||||
void fromString(const char* s, const extLong& p=defBigFloatInputDigits) {
|
||||
void fromString(const char* s, const extLong& p=get_static_defBigFloatInputDigits()) {
|
||||
rep->fromString(s, p);
|
||||
}
|
||||
/// convert to <tt>std::string</tt> (base = 10)
|
||||
std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const {
|
||||
std::string toString(long prec=get_static_defBigFloatOutputDigits(), bool sci=false) const {
|
||||
return rep->toString(prec, sci);
|
||||
}
|
||||
std::string str() const {
|
||||
|
|
@ -435,7 +442,7 @@ inline BigFloat operator* (const BigFloat& x, const BigFloat& y) {
|
|||
/// operator/
|
||||
inline BigFloat operator/ (const BigFloat& x, const BigFloat& y) {
|
||||
BigFloat z;
|
||||
z.getRep().div(x.getRep(),y.getRep(),defBFdivRelPrec);
|
||||
z.getRep().div(x.getRep(),y.getRep(),get_static_defBFdivRelPrec());
|
||||
return z;
|
||||
}
|
||||
|
||||
|
|
@ -490,12 +497,12 @@ inline BigFloat power(const BigFloat& x, unsigned long p) {
|
|||
/// The argument x is an initial approximation.
|
||||
BigFloat root(const BigFloat&, unsigned long k, const extLong&, const BigFloat&);
|
||||
inline BigFloat root(const BigFloat& x, unsigned long k) {
|
||||
return root(x, k, defBFsqrtAbsPrec, x);
|
||||
return root(x, k, get_static_defBFsqrtAbsPrec(), x);
|
||||
}
|
||||
|
||||
/// sqrt to defAbsPrec:
|
||||
inline BigFloat sqrt(const BigFloat& x) {
|
||||
return x.sqrt(defBFsqrtAbsPrec);
|
||||
return x.sqrt(get_static_defBFsqrtAbsPrec());
|
||||
}
|
||||
|
||||
/// convert an BigFloat Interval to a BigFloat with error bits
|
||||
|
|
@ -625,4 +632,10 @@ inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){
|
|||
*this = f.BigRatValue();
|
||||
}
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/BigFloat_impl.h>
|
||||
#include <CGAL/CORE/CoreIO_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_BIGFLOAT_H_
|
||||
|
|
|
|||
|
|
@ -40,6 +40,13 @@
|
|||
#include <CGAL/CORE/CoreDefs.h>
|
||||
#include <CGAL/CORE/extLong.h>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
// forward reference
|
||||
|
|
@ -144,11 +151,11 @@ private:
|
|||
// conversion
|
||||
|
||||
// toString() Joaquin Grech 31/5/2003
|
||||
std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const;
|
||||
std::string toString(long prec=get_static_defBigFloatOutputDigits(), bool sci=false) const;
|
||||
std::string round(std::string inRep, long& L10, unsigned int width) const;
|
||||
DecimalOutput toDecimal(unsigned int width=defBigFloatOutputDigits,
|
||||
DecimalOutput toDecimal(unsigned int width=get_static_defBigFloatOutputDigits(),
|
||||
bool Scientific=false) const;
|
||||
void fromString(const char *p, const extLong & prec = defBigFloatInputDigits);
|
||||
void fromString(const char *p, const extLong & prec = get_static_defBigFloatInputDigits());
|
||||
|
||||
void dump() const; //inline
|
||||
long adjustE(long E, BigInt M, long e) const;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -39,6 +39,13 @@
|
|||
#include <CGAL/CORE/MemoryPool.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
|
||||
|
|
@ -559,4 +566,9 @@ inline BigInt randomize(const BigInt& a) {
|
|||
//@}
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
//#include <CGAL/CORE/CoreIO_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_BIGINT_H_
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@
|
|||
#include <fstream>
|
||||
#include "CGAL/CORE/Impl.h"
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
#ifndef LONG_BIT // such as in Linux
|
||||
|
|
@ -181,4 +188,9 @@ inline void core_debug(std::string msg){
|
|||
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/CoreAux_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_COREAUX_H_
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
|
||||
#define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \
|
||||
inline TYPE & get_static_##NAME() \
|
||||
{ \
|
||||
static TYPE NAME = VALUE; \
|
||||
return NAME; \
|
||||
}
|
||||
|
||||
#else // CGAL_HEADER_ONLY
|
||||
|
||||
#define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \
|
||||
CGAL_EXPORT extern TYPE NAME; \
|
||||
inline TYPE& get_static_##NAME() \
|
||||
{ \
|
||||
return NAME; \
|
||||
}
|
||||
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
namespace CORE {
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
|
@ -60,34 +87,34 @@ namespace CORE {
|
|||
/** The normal behavior is to abort when an invalid expression
|
||||
* is constructed. This flag can be used to turn off this abort.
|
||||
* In any case, an error message will be printed */
|
||||
CGAL_CORE_EXPORT extern bool AbortFlag;
|
||||
CGAL_GLOBAL_STATE_VAR(bool, AbortFlag, true)
|
||||
|
||||
/// Invalid Flag -- initiallly value is non-negative
|
||||
/** If the Abort Flag is false, then the Invalid flag will be set to
|
||||
* a negative value whenever an invalid expression is constructed.
|
||||
* It is the user's responsibility to check this flag and to make
|
||||
* it non-negative again. */
|
||||
CGAL_CORE_EXPORT extern int InvalidFlag;
|
||||
CGAL_GLOBAL_STATE_VAR(int, InvalidFlag, 0)
|
||||
|
||||
/// Escape Precision in bits
|
||||
CGAL_CORE_EXPORT extern extLong EscapePrec;
|
||||
CGAL_GLOBAL_STATE_VAR(extLong, EscapePrec, CORE_posInfty)
|
||||
|
||||
/// current ur when EscapePrec triggered
|
||||
/** this flag becomes negative when default EscapePrec is applied */
|
||||
CGAL_CORE_EXPORT extern long EscapePrecFlag;
|
||||
CGAL_GLOBAL_STATE_VAR(long, EscapePrecFlag, 0)
|
||||
|
||||
/// Escape Precision Warning Flag
|
||||
/** this flag is true by default, and will cause a warning to be printed
|
||||
when EscapePrec is reached */
|
||||
CGAL_CORE_EXPORT extern bool EscapePrecWarning;
|
||||
CGAL_GLOBAL_STATE_VAR(bool, EscapePrecWarning, true)
|
||||
|
||||
// These following two values determine the precision of computing
|
||||
// approximations in Expr.
|
||||
|
||||
/// default Relative Precision in bits
|
||||
CGAL_CORE_EXPORT extern extLong defRelPrec;
|
||||
CGAL_GLOBAL_STATE_VAR(extLong, defRelPrec, 60)
|
||||
/// default Absolute Precision in bits
|
||||
CGAL_CORE_EXPORT extern extLong defAbsPrec;
|
||||
CGAL_GLOBAL_STATE_VAR(extLong, defAbsPrec, CORE_posInfty)
|
||||
|
||||
/// default # of decimal digits for conversion from a BF to string.
|
||||
/** This value cannot be CORE_INFTY.
|
||||
|
|
@ -97,42 +124,41 @@ CGAL_CORE_EXPORT extern extLong defAbsPrec;
|
|||
"controls the printout precision of std::cout for BigFloat"
|
||||
Perhaps, we should merge defOutputDigits and defBigFloatOutputDigits?
|
||||
*/
|
||||
CGAL_CORE_EXPORT extern long defBigFloatOutputDigits;
|
||||
CGAL_GLOBAL_STATE_VAR(long, defBigFloatOutputDigits, 10)
|
||||
|
||||
/// default input precision in digits for converting a string to a Real or Expr
|
||||
/** This value can be CORE_INFTY */
|
||||
CGAL_CORE_EXPORT extern extLong defInputDigits;
|
||||
CGAL_GLOBAL_STATE_VAR(extLong, defInputDigits, CORE_posInfty)
|
||||
|
||||
/// controls the printout precision of std::cout for Real and Expr
|
||||
/** This value cannot be CORE_INFTY
|
||||
See also defBigFloatOutputDigits.
|
||||
(it really should be an int, as in std::cout.setprecision(int)). */
|
||||
CGAL_CORE_EXPORT extern long defOutputDigits;
|
||||
CGAL_GLOBAL_STATE_VAR(long, defOutputDigits, get_static_defBigFloatOutputDigits())
|
||||
|
||||
/// default input precision in digits for converting a string to a BigFloat
|
||||
/** This value cannot be CORE_INFTY. */
|
||||
CGAL_CORE_EXPORT extern long defBigFloatInputDigits;
|
||||
CGAL_GLOBAL_STATE_VAR(long, defBigFloatInputDigits, 16)
|
||||
|
||||
/// default BigFloat Division Relative Precision
|
||||
CGAL_CORE_EXPORT extern extLong defBFdivRelPrec;
|
||||
|
||||
CGAL_GLOBAL_STATE_VAR(extLong, defBFdivRelPrec, 54)
|
||||
/// default BigFloat Sqrt Absolute Precision
|
||||
CGAL_CORE_EXPORT extern extLong defBFsqrtAbsPrec;
|
||||
CGAL_GLOBAL_STATE_VAR(extLong, defBFsqrtAbsPrec, 54)
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Mode parameters: incremental, progressive, filters
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
/// floating point filter flag
|
||||
CGAL_CORE_EXPORT extern bool fpFilterFlag;
|
||||
CGAL_GLOBAL_STATE_VAR(bool, fpFilterFlag, true)
|
||||
/// if true, evaluation of expressions would be incremental
|
||||
CGAL_CORE_EXPORT extern bool incrementalEvalFlag;
|
||||
CGAL_GLOBAL_STATE_VAR(bool, incrementalEvalFlag, true)
|
||||
/// progressive evaluation flag
|
||||
CGAL_CORE_EXPORT extern bool progressiveEvalFlag;
|
||||
CGAL_GLOBAL_STATE_VAR(bool, progressiveEvalFlag, true)
|
||||
/// rational reduction flag
|
||||
CGAL_CORE_EXPORT extern bool rationalReduceFlag;
|
||||
CGAL_GLOBAL_STATE_VAR(bool, rationalReduceFlag, false)
|
||||
/// default initial (bit) precision for AddSub Progressive Evaluation
|
||||
CGAL_CORE_EXPORT extern long defInitialProgressivePrec;
|
||||
CGAL_GLOBAL_STATE_VAR(long, defInitialProgressivePrec, 64)
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// methods for setting global precision parameters
|
||||
|
|
@ -144,87 +170,87 @@ CGAL_CORE_EXPORT extern long defInitialProgressivePrec;
|
|||
/** It determines the precision to which an Expr evaluates its
|
||||
(exact, implicit) constant value. */
|
||||
inline void setDefaultPrecision(const extLong &r, const extLong &a) {
|
||||
defRelPrec = r;
|
||||
defAbsPrec = a;
|
||||
get_static_defRelPrec() = r;
|
||||
get_static_defAbsPrec() = a;
|
||||
}
|
||||
|
||||
/// set default relative precision
|
||||
inline extLong setDefaultRelPrecision(const extLong &r) {
|
||||
extLong old = defRelPrec;
|
||||
defRelPrec = r;
|
||||
extLong old = get_static_defRelPrec();
|
||||
get_static_defRelPrec() = r;
|
||||
return old;
|
||||
}
|
||||
|
||||
/// set default absolute precision
|
||||
inline extLong setDefaultAbsPrecision(const extLong &a) {
|
||||
extLong old = defAbsPrec;
|
||||
defAbsPrec = a;
|
||||
extLong old = get_static_defAbsPrec();
|
||||
get_static_defAbsPrec() = a;
|
||||
return old;
|
||||
}
|
||||
|
||||
/// set default input digits (for Expr, Real)
|
||||
/** it controls the absolute error */
|
||||
inline extLong setDefaultInputDigits(const extLong &d) {
|
||||
extLong old = defInputDigits;
|
||||
defInputDigits = d;
|
||||
extLong old = get_static_defInputDigits();
|
||||
get_static_defInputDigits() = d;
|
||||
return old;
|
||||
}
|
||||
|
||||
/// set default output digits (for Expr, Real)
|
||||
inline long setDefaultOutputDigits(long d = defOutputDigits,
|
||||
inline long setDefaultOutputDigits(long d = get_static_defOutputDigits(),
|
||||
std::ostream& o = std::cout) {
|
||||
long old = defOutputDigits;
|
||||
defOutputDigits = d;
|
||||
long old = get_static_defOutputDigits();
|
||||
get_static_defOutputDigits() = d;
|
||||
o.precision(d);
|
||||
return old;
|
||||
}
|
||||
|
||||
/// set default input digits for BigFloat
|
||||
inline long setDefaultBFInputDigits(long d) {
|
||||
long old = defBigFloatInputDigits;
|
||||
defBigFloatInputDigits = d;
|
||||
long old = get_static_defBigFloatInputDigits();
|
||||
get_static_defBigFloatInputDigits() = d;
|
||||
return old;
|
||||
}
|
||||
|
||||
/// set default output digits for BigFloat
|
||||
inline long setDefaultBFOutputDigits(long d) {
|
||||
long old = defBigFloatOutputDigits;
|
||||
defBigFloatOutputDigits = d;
|
||||
long old = get_static_defBigFloatOutputDigits();
|
||||
get_static_defBigFloatOutputDigits() = d;
|
||||
return old;
|
||||
}
|
||||
|
||||
/// turn floating-point filter on/off
|
||||
inline bool setFpFilterFlag(bool f) {
|
||||
bool oldf = fpFilterFlag;
|
||||
fpFilterFlag = f;
|
||||
bool oldf = get_static_fpFilterFlag();
|
||||
get_static_fpFilterFlag() = f;
|
||||
return oldf;
|
||||
}
|
||||
|
||||
/// turn incremental evaluation flag on/off
|
||||
inline bool setIncrementalEvalFlag(bool f) {
|
||||
bool oldf = incrementalEvalFlag;
|
||||
incrementalEvalFlag = f;
|
||||
bool oldf = get_static_incrementalEvalFlag();
|
||||
get_static_incrementalEvalFlag() = f;
|
||||
return oldf;
|
||||
}
|
||||
|
||||
/// turn progressive evaluation flag on/off
|
||||
inline bool setProgressiveEvalFlag(bool f) {
|
||||
bool oldf = progressiveEvalFlag;
|
||||
progressiveEvalFlag = f;
|
||||
bool oldf = get_static_progressiveEvalFlag();
|
||||
get_static_progressiveEvalFlag() = f;
|
||||
return oldf;
|
||||
}
|
||||
|
||||
/// set initial bit precision for progressive evaluation:
|
||||
inline long setDefInitialProgressivePrec(long n) {
|
||||
long oldn = defInitialProgressivePrec;
|
||||
defInitialProgressivePrec = n;
|
||||
long oldn = get_static_defInitialProgressivePrec();
|
||||
get_static_defInitialProgressivePrec() = n;
|
||||
return oldn;
|
||||
}
|
||||
|
||||
/// turn rational reduction flag on/off
|
||||
inline bool setRationalReduceFlag(bool f) {
|
||||
bool oldf = rationalReduceFlag;
|
||||
rationalReduceFlag = f;
|
||||
bool oldf = get_static_rationalReduceFlag();
|
||||
get_static_rationalReduceFlag() = f;
|
||||
return oldf;
|
||||
}
|
||||
|
||||
|
|
@ -235,9 +261,9 @@ inline bool setRationalReduceFlag(bool f) {
|
|||
e.g., overriding the default std::cout precision (most systems
|
||||
initializes this value to 6) to our own */
|
||||
inline void CORE_init(long d) {
|
||||
defAbsPrec = CORE_posInfty;
|
||||
defOutputDigits = d;
|
||||
std::setprecision(defOutputDigits);
|
||||
get_static_defAbsPrec() = CORE_posInfty;
|
||||
get_static_defOutputDigits() = d;
|
||||
std::setprecision(get_static_defOutputDigits());
|
||||
}
|
||||
|
||||
/// change to scientific output format
|
||||
|
|
@ -251,4 +277,9 @@ inline void setPositionalFormat(std::ostream& o = std::cout) {
|
|||
}
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/CoreDefs_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_COREDEFS_H_
|
||||
|
|
|
|||
|
|
@ -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$
|
||||
***************************************************************************/
|
||||
|
||||
// We need to include BigFloat.h here because there is a circular dependency
|
||||
// between Expr and BigFloat.
|
||||
#include <CGAL/CORE/BigFloat.h>
|
||||
|
||||
#ifndef _CORE_EXPR_H_
|
||||
#define _CORE_EXPR_H_
|
||||
|
||||
#include <CGAL/CORE/ExprRep.h>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
/// \class Expr Expr.h
|
||||
|
|
@ -78,9 +89,9 @@ public:
|
|||
// (i.e., not infinite and not NaN)
|
||||
if (! CGAL_CORE_finite(f)) {
|
||||
std::cerr << " ERROR : constructed an invalid float! " << std::endl;
|
||||
if (AbortFlag)
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
InvalidFlag = -1;
|
||||
get_static_InvalidFlag() = -1;
|
||||
}
|
||||
rep = new ConstDoubleRep(f);
|
||||
}
|
||||
|
|
@ -89,9 +100,9 @@ public:
|
|||
// (i.e., not infinite and not NaN)
|
||||
if (! CGAL_CORE_finite(d)) {
|
||||
std::cerr << " ERROR : constructed an invalid double! " << std::endl;
|
||||
if (AbortFlag)
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
InvalidFlag = -2;
|
||||
get_static_InvalidFlag() = -2;
|
||||
}
|
||||
rep = new ConstDoubleRep(d);
|
||||
}
|
||||
|
|
@ -111,11 +122,11 @@ public:
|
|||
* it is generally recommended that the (String) constructor be used in
|
||||
* preference to the (double) constructor.
|
||||
*/
|
||||
Expr(const char *s, const extLong& p = defInputDigits)
|
||||
Expr(const char *s, const extLong& p = get_static_defInputDigits())
|
||||
: RCExpr(new ConstRealRep(Real(s, p))) {}
|
||||
|
||||
/// constructor for <tt>std::string</tt>
|
||||
Expr(const std::string& s, const extLong& p = defInputDigits)
|
||||
Expr(const std::string& s, const extLong& p = get_static_defInputDigits())
|
||||
: RCExpr(new ConstRealRep(Real(s, p))) {}
|
||||
|
||||
/// constructor for <tt>Real</tt>
|
||||
|
|
@ -179,9 +190,9 @@ public:
|
|||
Expr& operator/=(const Expr& e) {
|
||||
if ((e.rep)->getSign() == 0) {
|
||||
std::cerr << " ERROR : division by zero ! " << std::endl;
|
||||
if (AbortFlag)
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
InvalidFlag = -3;
|
||||
get_static_InvalidFlag() = -3;
|
||||
}
|
||||
*this = new DivRep(rep, e.rep);
|
||||
return *this;
|
||||
|
|
@ -225,12 +236,12 @@ public:
|
|||
/// \name String Conversion Functions
|
||||
//@{
|
||||
/// set value from <tt>const char*</tt>
|
||||
void fromString(const char* s, const extLong& prec = defInputDigits) {
|
||||
void fromString(const char* s, const extLong& prec = get_static_defInputDigits()) {
|
||||
*this = Expr(s, prec);
|
||||
}
|
||||
/// convert to <tt>std::string</tt>
|
||||
/** give decimal string representation */
|
||||
std::string toString(long prec=defOutputDigits, bool sci=false) const {
|
||||
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) const {
|
||||
return rep->toString(prec, sci);
|
||||
}
|
||||
//@}
|
||||
|
|
@ -282,8 +293,8 @@ public:
|
|||
/** Here is the definition of what this means:
|
||||
If e is the exact value and ee is the approximate value,
|
||||
then |e - ee| <= 2^{-a} or |e - ee| <= 2^{-r} |e|. */
|
||||
const Real & approx(const extLong& relPrec = defRelPrec,
|
||||
const extLong& absPrec = defAbsPrec) const {
|
||||
const Real & approx(const extLong& relPrec = get_static_defRelPrec(),
|
||||
const extLong& absPrec = get_static_defAbsPrec()) const {
|
||||
return rep->getAppValue(relPrec, absPrec);
|
||||
}
|
||||
//@}
|
||||
|
|
@ -355,7 +366,7 @@ inline std::ostream& operator<<(std::ostream& o, const Expr& e) {
|
|||
/// I/O Stream operator>>
|
||||
inline std::istream& operator>>(std::istream& i, Expr& e) {
|
||||
Real rVal;
|
||||
i >> rVal; // precision is = defInputDigits
|
||||
i >> rVal; // precision is = get_static_defInputDigits()
|
||||
if (i)
|
||||
e = rVal; // only assign when reading is successful.
|
||||
return i;
|
||||
|
|
@ -382,9 +393,9 @@ inline Expr operator*(const Expr& e1, const Expr& e2) {
|
|||
inline Expr operator/(const Expr& e1, const Expr& e2) {
|
||||
if (e2.sign() == 0) {
|
||||
std::cerr << " ERROR : division by zero ! " << std::endl;
|
||||
if (AbortFlag)
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
InvalidFlag = -4;
|
||||
get_static_InvalidFlag() = -4;
|
||||
}
|
||||
return Expr(new DivRep(e1.Rep(), e2.Rep()));
|
||||
}
|
||||
|
|
@ -485,9 +496,9 @@ inline bool isDivisible(const Expr& e1, const Expr& e2) {
|
|||
inline Expr sqrt(const Expr& e) {
|
||||
if (e.sign() < 0) {
|
||||
std::cerr << " ERROR : sqrt of negative value ! " << std::endl;
|
||||
if (AbortFlag)
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
InvalidFlag = -5;
|
||||
get_static_InvalidFlag() = -5;
|
||||
}
|
||||
return Expr(new SqrtRep(e.Rep()));
|
||||
}
|
||||
|
|
@ -548,4 +559,9 @@ inline Expr radical(const NT& n, int m) {
|
|||
#include <CGAL/CORE/poly/Poly.tcc>
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/Expr_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_EXPR_H_
|
||||
|
|
|
|||
|
|
@ -43,9 +43,16 @@
|
|||
#include <CGAL/CORE/Filter.h>
|
||||
#include <CGAL/CORE/poly/Sturm.h>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
#ifdef CORE_DEBUG_BOUND
|
||||
#if defined(CORE_DEBUG_BOUND) && !defined(CGAL_HEADER_ONLY)
|
||||
// These counters are incremented each time each bound is recognized as equal
|
||||
// to the best one in computeBound().
|
||||
extern unsigned int BFMSS_counter;
|
||||
|
|
@ -189,8 +196,8 @@ public:
|
|||
/// \name Helper Functions
|
||||
//@{
|
||||
/// Get the approximate value
|
||||
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = defRelPrec,
|
||||
const extLong& absPrec = defAbsPrec);
|
||||
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = get_static_defRelPrec(),
|
||||
const extLong& absPrec = get_static_defAbsPrec());
|
||||
/// Get the sign.
|
||||
int getSign();
|
||||
int getExactSign();
|
||||
|
|
@ -389,8 +396,8 @@ public:
|
|||
BigFloat BigFloatValue();
|
||||
/// represent as a string in decimal value
|
||||
// toString() Joaquin Grech 31/5/2003
|
||||
std::string toString(long prec=defOutputDigits, bool sci=false) {
|
||||
return (getAppValue(defRelPrec, defAbsPrec)).toString(prec,sci);
|
||||
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) {
|
||||
return (getAppValue(get_static_defRelPrec(), get_static_defAbsPrec())).toString(prec,sci);
|
||||
}
|
||||
//@}
|
||||
|
||||
|
|
@ -677,7 +684,7 @@ protected:
|
|||
tc() = ceilLg(ss.seq[0].getTailCoeff());
|
||||
|
||||
// no rational reduction
|
||||
if (rationalReduceFlag)
|
||||
if (get_static_rationalReduceFlag())
|
||||
ratFlag() = -1;
|
||||
|
||||
flagsComputed() = true;
|
||||
|
|
@ -838,7 +845,12 @@ protected:
|
|||
/// \brief "functor" class used as parameter to AddSubRep<>
|
||||
struct Add {
|
||||
/// name
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
CGAL_CORE_EXPORT static const char* name;
|
||||
#endif
|
||||
static const char* get_name() {
|
||||
return "+";
|
||||
}
|
||||
|
||||
/// unary operator
|
||||
template <class T>
|
||||
|
|
@ -857,7 +869,12 @@ struct Add {
|
|||
/// \brief "functor" class used as parameter to AddSubRep<>
|
||||
struct Sub {
|
||||
/// name
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
CGAL_CORE_EXPORT static const char* name;
|
||||
#endif
|
||||
static const char* get_name() {
|
||||
return "-";
|
||||
}
|
||||
|
||||
/// unary operator
|
||||
template <class T>
|
||||
|
|
@ -895,7 +912,7 @@ protected:
|
|||
void computeApproxValue(const extLong&, const extLong&);
|
||||
/// return operator in string
|
||||
const std::string op() const {
|
||||
return Operator::name;
|
||||
return Operator::get_name();
|
||||
}
|
||||
private:
|
||||
static Operator Op;
|
||||
|
|
@ -925,7 +942,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
reduceTo(second);
|
||||
sign() = Op(ss);
|
||||
appValue() = Op(appValue());
|
||||
if (rationalReduceFlag && ratFlag() > 0)
|
||||
if (get_static_rationalReduceFlag() && ratFlag() > 0)
|
||||
*(ratValue()) = Op(*(ratValue()));
|
||||
return;
|
||||
} else if (ss == 0) { // second operand is zero
|
||||
|
|
@ -933,7 +950,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
return;
|
||||
}
|
||||
// rational node
|
||||
if (rationalReduceFlag) {
|
||||
if (get_static_rationalReduceFlag()) {
|
||||
if (first->ratFlag() > 0 && second->ratFlag() > 0) {
|
||||
BigRat val=Op(*(first->ratValue()), *(second->ratValue()));
|
||||
reduceToBigRat(val);
|
||||
|
|
@ -1046,7 +1063,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
if (lowBound <= EXTLONG_ZERO)
|
||||
lowBound = EXTLONG_ONE;
|
||||
|
||||
if (!progressiveEvalFlag) {
|
||||
if (!get_static_progressiveEvalFlag()) {
|
||||
// convert the absolute error requirement "lowBound" to
|
||||
// a relative error requirement "ur", s.t.
|
||||
// |x|*2^(-ur) <= 2^(-lowBound).
|
||||
|
|
@ -1085,7 +1102,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
// larger than lowBound AND the defaultInitialProgressivePrec,
|
||||
// so that we do at least one iteration of the for-loop. So:
|
||||
// i is the variable for iteration.
|
||||
extLong i = core_min(defInitialProgressivePrec, lowBound.asLong());
|
||||
extLong i = core_min(get_static_defInitialProgressivePrec(), lowBound.asLong());
|
||||
extLong ua = lowBound.asLong() + EXTLONG_ONE;
|
||||
// NOTE: ua is allowed to be CORE_INFTY
|
||||
|
||||
|
|
@ -1096,7 +1113,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
lMSB() = CORE_negInfty;
|
||||
sign() = 0;
|
||||
|
||||
EscapePrecFlag = 0; // reset the Escape Flag
|
||||
get_static_EscapePrecFlag() = 0; // reset the Escape Flag
|
||||
|
||||
// Now we try to determine the real lMSB and sign,
|
||||
// in case it is not really zero:
|
||||
|
|
@ -1151,22 +1168,22 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
break; // assert -- this must happen in the loop if nonzero!
|
||||
}
|
||||
//8/9/01, Chee: implement escape precision here:
|
||||
if (i> EscapePrec) {
|
||||
EscapePrecFlag = -i.asLong();//negative means EscapePrec is used
|
||||
if (i> get_static_EscapePrec()) {
|
||||
get_static_EscapePrecFlag() = -i.asLong();//negative means EscapePrec is used
|
||||
core_error("Escape precision triggered at",
|
||||
__FILE__, __LINE__, false);
|
||||
if (EscapePrecWarning)
|
||||
if (get_static_EscapePrecWarning())
|
||||
std::cout<< "Escape Precision triggered at "
|
||||
<< EscapePrec << " bits" << std::endl;
|
||||
<< get_static_EscapePrec() << " bits" << std::endl;
|
||||
#ifdef CORE_DEBUG
|
||||
std::cout << "EscapePrecFlags=" << EscapePrecFlag << std::endl;
|
||||
std::cout << "EscapePrecFlags=" << get_static_EscapePrecFlag() << std::endl;
|
||||
std::cout << "ua =" << ua << ",lowBound=" << lowBound << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}// if
|
||||
}// for (long i=1...)
|
||||
|
||||
#ifdef CORE_DEBUG_BOUND
|
||||
#if defined(CORE_DEBUG_BOUND) && !defined(CGAL_HEADER_ONLY)
|
||||
rootBoundHitCounter++;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -42,6 +42,13 @@
|
|||
#include <CGAL/CORE/Real.h>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
#if !defined CGAL_CFG_NO_CPP0X_ISFINITE
|
||||
#define CGAL_CORE_finite(x) std::isfinite(x)
|
||||
#elif defined (_MSC_VER) || defined (__MINGW32__) // add support for MinGW
|
||||
|
|
@ -102,7 +109,7 @@ public:
|
|||
}
|
||||
/// check whether the sign (!) of the filtered value is OK
|
||||
bool isOK() const {
|
||||
return (fpFilterFlag && // To disable filter
|
||||
return (get_static_fpFilterFlag() && // To disable filter
|
||||
CGAL_CORE_finite(fpVal) && // Test for infinite and NaNs
|
||||
(core_abs(fpVal) >= maxAbs*ind*CORE_EPS));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@
|
|||
#include <CGAL/CORE/Impl.h>
|
||||
#include <gmp.h>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpz_srcptr);
|
||||
|
|
@ -39,4 +46,9 @@ CGAL_CORE_EXPORT std::istream& io_read (std::istream &, mpq_ptr);
|
|||
//std::istream& operator>> (std::istream &, mpq_ptr);
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/Gmp_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_GMP_H_
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
#include "RealRep.h"
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
// class Real
|
||||
typedef RCImpl<RealRep> RCReal;
|
||||
|
|
@ -57,10 +64,10 @@ public:
|
|||
Real(const BigInt& I) : RCReal(new RealBigInt(I)) {}
|
||||
Real(const BigRat& R) : RCReal(new RealBigRat(R)) {}
|
||||
Real(const BigFloat& F) : RCReal(new RealBigFloat(F)) {}
|
||||
Real(const char* s, const extLong& prec=defInputDigits) : RCReal(NULL) {
|
||||
Real(const char* s, const extLong& prec=get_static_defInputDigits()) : RCReal(NULL) {
|
||||
constructFromString(s, prec);
|
||||
}
|
||||
Real(const std::string& s, const extLong& prec=defInputDigits) : RCReal(NULL){
|
||||
Real(const std::string& s, const extLong& prec=get_static_defInputDigits()) : RCReal(NULL){
|
||||
constructFromString(s.c_str(), prec);
|
||||
}
|
||||
|
||||
|
|
@ -134,12 +141,12 @@ public:
|
|||
/// \name String Conversion Functions
|
||||
//@{
|
||||
/// set value from <tt>const char*</tt>
|
||||
void fromString(const char* s, const extLong& prec = defInputDigits) {
|
||||
void fromString(const char* s, const extLong& prec = get_static_defInputDigits()) {
|
||||
*this = Real(s, prec);
|
||||
}
|
||||
/// convert to <tt>std::string</tt>
|
||||
/** give decimal string representation */
|
||||
std::string toString(long prec=defOutputDigits, bool sci=false) const {
|
||||
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) const {
|
||||
return rep->toString(prec, sci);
|
||||
}
|
||||
//@}
|
||||
|
|
@ -179,7 +186,8 @@ public:
|
|||
/// \name Aprroximation Function
|
||||
//@{
|
||||
/// approximation
|
||||
Real approx(const extLong& r=defRelPrec, const extLong& a=defAbsPrec) const {
|
||||
Real approx(const extLong& r=get_static_defRelPrec(),
|
||||
const extLong& a=get_static_defAbsPrec()) const {
|
||||
return rep->approx(r, a);
|
||||
}
|
||||
//@}
|
||||
|
|
@ -395,7 +403,7 @@ inline Real& Real::operator*=(const Real& rhs) {
|
|||
return *this;
|
||||
}
|
||||
inline Real& Real::operator/=(const Real& rhs) {
|
||||
*this = real_div::eval(getRep(), rhs.getRep(), defRelPrec);
|
||||
*this = real_div::eval(getRep(), rhs.getRep(), get_static_defRelPrec());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -413,7 +421,7 @@ inline Real operator*(const Real& x, const Real& y) {
|
|||
}
|
||||
// operator/
|
||||
inline Real operator/(const Real& x, const Real& y) {
|
||||
return real_div::eval(x.getRep(), y.getRep(), defRelPrec);
|
||||
return real_div::eval(x.getRep(), y.getRep(), get_static_defRelPrec());
|
||||
}
|
||||
// div w/ precision
|
||||
inline Real Real::div(const Real& x, const extLong& r) const {
|
||||
|
|
@ -478,7 +486,7 @@ inline Real power(const Real& r, unsigned long p) {
|
|||
}
|
||||
/// square root
|
||||
inline Real sqrt(const Real& x) {
|
||||
return x.sqrt(defAbsPrec);
|
||||
return x.sqrt(get_static_defAbsPrec());
|
||||
}
|
||||
|
||||
// class Realbase_for (need defined after Real)
|
||||
|
|
@ -493,4 +501,9 @@ inline Real RealLong::operator-() const {
|
|||
}
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/Real_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_REAL_H_
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@
|
|||
#include <CGAL/CORE/Impl.h>
|
||||
#include <CGAL/CORE/CoreAux.h>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#undef CGAL_EXPORT // CJTODO: TEMPORARY
|
||||
#undef CGAL_CORE_EXPORT
|
||||
#define CGAL_EXPORT
|
||||
#define CGAL_CORE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
#ifndef LONG_MAX
|
||||
|
|
@ -294,4 +301,9 @@ inline bool extLong::isNaN() const {
|
|||
}
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/extLong_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#endif // _CORE_EXTLONG_H_
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ public:
|
|||
/// Polynomial evaluation where the coefficients are approximated first
|
||||
/// Returns a BigFloat with error that contains the value
|
||||
BigFloat evalApprox(const BigFloat& f,
|
||||
const extLong& r=defRelPrec, const extLong& a=defAbsPrec) const;
|
||||
const extLong& r=get_static_defRelPrec(),
|
||||
const extLong& a=get_static_defAbsPrec()) const;
|
||||
/// Polynomial evaluation at a BigFloat value.
|
||||
/// The returned BigFloat (with error) has the exact sign.
|
||||
/// In particular, if the value is 0, we return 0.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -33,181 +33,9 @@
|
|||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "CGAL/CORE/CoreAux.h"
|
||||
#include <gmp.h>
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
|
||||
namespace CORE {
|
||||
#include <CGAL/CORE/CoreAux.h>
|
||||
#include <CGAL/CORE/CoreAux_impl.h>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// More useful functions to implement:
|
||||
//
|
||||
// To convert digits into bits:
|
||||
// given X, compute X * log_2(10)
|
||||
// To convert bits into digits:
|
||||
// given X, compute X * log_10(2)
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// flrLg(x)
|
||||
// returns floor log base 2 of abs(x)
|
||||
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
|
||||
////////////////////////////////////////////////////////////
|
||||
int flrLg(long x) {
|
||||
if (x == LONG_MIN) {
|
||||
// special treatment as -LONG_MIN would be not representable as "long"
|
||||
return LONG_BIT - 1;
|
||||
} else {
|
||||
// 1 <= |x| <= LONG_MAX
|
||||
if (x < 0)
|
||||
x = - x;
|
||||
|
||||
int lg = -1;
|
||||
while (x > 0) {
|
||||
lg++;
|
||||
x >>= 1;
|
||||
}
|
||||
return lg;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// floor log base 2 of unsigned long x
|
||||
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
|
||||
////////////////////////////////////////////////////////////
|
||||
int flrLg(unsigned long x) {
|
||||
int lg = -1;
|
||||
while (x > 0) {
|
||||
lg++;
|
||||
x >>= 1;
|
||||
}
|
||||
return lg;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// ceiling log base 2 of abs(x)
|
||||
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
|
||||
////////////////////////////////////////////////////////////
|
||||
int clLg(long x) {
|
||||
if (x == LONG_MIN)
|
||||
return LONG_BIT - 1;
|
||||
if (x < 0)
|
||||
x = -x; // use absolute value
|
||||
if (x > (LONG_MAX >> 1)) // the leading data bit is 1
|
||||
return (LONG_BIT - 1); // exclude the sign bit
|
||||
if (x >= 2)
|
||||
return flrLg((unsigned long)((x << 1) - 1));
|
||||
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2
|
||||
if (x == 1)
|
||||
return 0;
|
||||
return -1; // x must be 0 here
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// ceiling log base 2 of unsigned long x
|
||||
// CONVENTION lg(0) = -1
|
||||
////////////////////////////////////////////////////////////
|
||||
int clLg(unsigned long x) {
|
||||
if (x > (ULONG_MAX >> 1)) // the leading bit is 1
|
||||
return LONG_BIT;
|
||||
if (x >= 2)
|
||||
return flrLg((x << 1) - 1);
|
||||
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2.
|
||||
if (x == 1)
|
||||
return 0;
|
||||
return -1; // x must be equal to 0
|
||||
}
|
||||
|
||||
/// gcd for machine type long
|
||||
/** This is needed when we construct Polynomials with int or long coefficients */
|
||||
long gcd(long m, long n) {
|
||||
if (m == 0)
|
||||
return core_abs(n);
|
||||
if (n == 0)
|
||||
return core_abs(m);
|
||||
long p = core_abs(m);
|
||||
long q = core_abs(n);
|
||||
if (p<q)
|
||||
core_swap(p, q);
|
||||
while (q>0) {
|
||||
long r = p % q;
|
||||
p = q;
|
||||
q = r;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
// return a gmp_randstate_t structure
|
||||
gmp_randstate_t* getRandstate() {
|
||||
static gmp_randstate_t rstate;
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
gmp_randinit(rstate, GMP_RAND_ALG_DEFAULT, 32L);
|
||||
initialized = true;
|
||||
}
|
||||
return &rstate;
|
||||
}
|
||||
|
||||
// char* core_itoa(int n, char* buffer)
|
||||
// returns a pointer to the null-terminated string in buffer
|
||||
// NOTES:
|
||||
// 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit
|
||||
// (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes.
|
||||
// 1. itoa(...) is available on some stdlib.h, but it is
|
||||
// not defined by ANSI-C and so not all compilers support it.
|
||||
// 2. Our use of sprintf(...) to do the job is known to
|
||||
// be inefficient, but this is hardly critical for our usage.
|
||||
// 3. A more general program should take a 3rd argument (the radix of
|
||||
// output number). We assume radix 10.
|
||||
char * core_itoa(int n, char* buffer) {
|
||||
std::sprintf(buffer, "%d", n);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// implements the "integer mantissa" function
|
||||
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
|
||||
double IntMantissa(double d) {
|
||||
int e;
|
||||
return std::ldexp(std::frexp(d, &e), 53);
|
||||
}
|
||||
|
||||
/// implements the "integer exponent" function
|
||||
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
|
||||
int IntExponent(double d) {
|
||||
int e;
|
||||
std::frexp(d, &e);
|
||||
return e-53;
|
||||
}
|
||||
|
||||
/// CORE_DIAGFILE is file name for core_error(..) output.
|
||||
const char* CORE_DIAGFILE = "Core_Diagnostics"; // global file name
|
||||
|
||||
/// core_error is the method to write Core Library warning or error messages
|
||||
/** Both warnings and errors are written to a file called CORE_DIAGFILE.
|
||||
* But errors are also written on std:cerr (similar to std::perror()).
|
||||
* */
|
||||
// Usage: core_error(message, file_with_error, line_number, err_type)
|
||||
// where err_type=0 means WARNING, error_type=0 means ERROR
|
||||
void core_error(std::string msg, std::string file, int lineno, bool err) {
|
||||
std::ofstream outFile(CORE_DIAGFILE, std::ios::app); // open to append
|
||||
if (!outFile) {
|
||||
// perror("CORE ERROR: cannot open Core Diagnostics file");
|
||||
std::cerr << "CORE ERROR: can't open Core Diagnostics file"<<std::endl;
|
||||
std::exit(1); //Note: do not call abort()
|
||||
}
|
||||
outFile << "CORE " << (err? "ERROR" : "WARNING")
|
||||
<< " (at " << file << ": " << lineno << "): "
|
||||
<< msg << std::endl;
|
||||
outFile.close();
|
||||
if (err) {
|
||||
char buf[65];
|
||||
// perror((std::string("CORE ERROR") + " (file " + file + ", line "
|
||||
// + core_itoa(lineno,buf) +"):" + msg + "\n").c_str());
|
||||
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
|
||||
+ core_itoa(lineno,buf) +"):" + msg + "\n").c_str();
|
||||
std::exit(1); //Note: do not call abort()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace CORE
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,124 +32,9 @@
|
|||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include "CGAL/CORE/CoreDefs.h"
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
|
||||
namespace CORE {
|
||||
|
||||
// Default Values
|
||||
|
||||
/* ************************************************************
|
||||
* ERROR FLAGS
|
||||
* ************************************************************ */
|
||||
|
||||
/** I/O error flag (Default value 0, indicating no error)
|
||||
* User's responsibility to check and reset value to 0. */
|
||||
// This is currently used in geom2d/points2d.cpp for I/O of points
|
||||
|
||||
int IOErrorFlag = 0;
|
||||
|
||||
/**
|
||||
* If AbortFlag is true when invalid expression is constructed, system will abort
|
||||
*/
|
||||
|
||||
bool AbortFlag = true;
|
||||
|
||||
/**
|
||||
* InvalidFlag is set to negative whenever an invalid expression is constructed.
|
||||
* The user has the responsibility to reset to non-negative value.
|
||||
*/
|
||||
|
||||
int InvalidFlag = 0;
|
||||
|
||||
/* ************************************************************
|
||||
* PRECISION PARAMETERS
|
||||
* ************************************************************ */
|
||||
|
||||
/**
|
||||
* Default BigFloat Division Relative Precision
|
||||
* -- this is used by BigFloat division when the arguments are error-free.
|
||||
*/
|
||||
|
||||
extLong defBFdivRelPrec = 54;
|
||||
|
||||
/**
|
||||
* Default BigFloat Sqrt Absolute Precision
|
||||
* -- this is used by BigFloat sqrt when the argument is error-free.
|
||||
*/
|
||||
|
||||
extLong defBFsqrtAbsPrec = 54;
|
||||
|
||||
/**
|
||||
* Escape Precision
|
||||
* -- we will not compare a number to precision higher than this
|
||||
* -- if this is infinity, there there is no escape precision */
|
||||
extLong EscapePrec = CORE_posInfty;
|
||||
|
||||
/** this flag becomes negative if the EscapePrec is used. */
|
||||
long EscapePrecFlag = 0;
|
||||
|
||||
/// Escape Precision Warning Flag
|
||||
/** this flag is true by default, and will cause a warning to be printed
|
||||
when EscapePrec is reached */
|
||||
bool EscapePrecWarning = true;
|
||||
|
||||
/** The Composite Precision [defAbsPrec, defRelPrec]
|
||||
* determines the precision to which an Expr evaluates its
|
||||
* (exact, implicit) constant value. */
|
||||
|
||||
/** absolute precision = 2^31 - 1 */
|
||||
extLong defAbsPrec = CORE_posInfty;
|
||||
/** default relative precision is 60 relative bits.
|
||||
* Why 60? We would really like this to be 54, so that the default
|
||||
* conversion duplicates the IEEE double precision. But it turns out
|
||||
* (see README file under BUGS), we need 59 to ensure this.
|
||||
* Chee Yap (7/1/01) */
|
||||
extLong defRelPrec = 60;
|
||||
|
||||
/** number of BigFloat digits to print out */
|
||||
long defBigFloatOutputDigits = 10;
|
||||
|
||||
/** NORMALLY, we like to make this equal to defBigFloatOutputDigits
|
||||
* 8/3/01, Chee: re-introduced this parameter */
|
||||
long defOutputDigits = defBigFloatOutputDigits;
|
||||
|
||||
/** String Input Precision */
|
||||
|
||||
/** Set this to 16 if you want machine precision. This controls the
|
||||
* absolute error in string decimal inputs to Real or Expr.
|
||||
* If defInputDigits is finite, then the absolute error will be
|
||||
* at most 10^{-defInputDigits}. Otherwise, the input is exactly
|
||||
* represented by some BigFloat or BigRat value. */
|
||||
extLong defInputDigits = CORE_posInfty;
|
||||
|
||||
/** This controls the absolute error in converting from string to BigFloat
|
||||
* The absolute error will be at most 10^{-defInputDigits} */
|
||||
long defBigFloatInputDigits = 16;
|
||||
|
||||
/* ************************************************************
|
||||
* EVALUATION FLAGS
|
||||
* ************************************************************ */
|
||||
|
||||
/** Floating Point filter
|
||||
* true = turn on floating point filter */
|
||||
bool fpFilterFlag = true;
|
||||
|
||||
/** IncrementaL evaluation flag
|
||||
* incremental evaluation is requested, This means, we try to use previous
|
||||
* approximate values to improve an approximation */
|
||||
bool incrementalEvalFlag = true;
|
||||
|
||||
/** Progressive evaluation flag
|
||||
* true = turn on progressive evaluation flag */
|
||||
bool progressiveEvalFlag = true;
|
||||
|
||||
/** Initial progressive evaluation precision
|
||||
* Used by AddSubRep */
|
||||
long defInitialProgressivePrec = 64;
|
||||
|
||||
/** RATIONAL REDUCTION FLAG
|
||||
* true = turn on rational reduction */
|
||||
bool rationalReduceFlag = false;
|
||||
|
||||
} //namespace CORE
|
||||
#include <CGAL/CORE/CoreDefs.h>
|
||||
#include <CGAL/CORE/CoreDefs_impl.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,430 +29,6 @@
|
|||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include <CGAL/CORE/BigFloatRep.h>
|
||||
#include <CGAL/CORE/BigFloat.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
void core_io_error_handler(const char *f, const char *m) {
|
||||
std::cout << "\n error_handler";
|
||||
std::cout << "::" << f << "::" << m << "\n";
|
||||
std::cout.flush();
|
||||
std::abort();
|
||||
}
|
||||
|
||||
void core_io_memory_handler(char *t, const char *f, const char *m) {
|
||||
if (t == NULL) {
|
||||
std::cout << "\n memory_handler";
|
||||
std::cout << "::" << f << "::" << m;
|
||||
std::cout << "memory exhausted\n";
|
||||
std::cout.flush();
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
// s has size old_size and will be resized to new_size.
|
||||
void allocate (char * &s, int old_size, int new_size) {
|
||||
if (old_size > new_size)
|
||||
old_size = new_size;
|
||||
|
||||
if (s == NULL)
|
||||
old_size = 0;
|
||||
|
||||
char *t = new char[new_size];
|
||||
core_io_memory_handler(t, "CoreIO", "allocate::out of memory error");
|
||||
|
||||
int i;
|
||||
for (i = 0; i < old_size; i++)
|
||||
t[i] = s[i];
|
||||
|
||||
delete[] s;
|
||||
s = t;
|
||||
}
|
||||
|
||||
// appends c to s at position pos.
|
||||
// sz is the size of s
|
||||
void append_char (char * &s, int & sz, int pos, char c) {
|
||||
if (pos > sz)
|
||||
core_io_error_handler("CoreIO", "append_char::invalid argument");
|
||||
|
||||
if (pos == sz) {
|
||||
allocate(s, sz, 2*sz);
|
||||
sz *= 2;
|
||||
}
|
||||
|
||||
s[pos] = c;
|
||||
}
|
||||
|
||||
// skip blanks, tabs, line breaks and comment lines
|
||||
int skip_comment_line (std::istream & in) {
|
||||
int c;
|
||||
|
||||
do {
|
||||
c = in.get();
|
||||
while ( c == '#' ) {
|
||||
do {
|
||||
c = in.get();
|
||||
} while ( c != '\n' );
|
||||
c = in.get();
|
||||
}
|
||||
} while (c == ' ' || c == '\t' || c == '\n');
|
||||
|
||||
if (c == EOF)
|
||||
core_io_error_handler("CoreIO::read_from_file()","unexpected end of file.");
|
||||
|
||||
in.putback(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
// skips '\\' followed by '\n'
|
||||
int skip_backslash_new_line (std::istream & in) {
|
||||
int c = in.get();
|
||||
|
||||
while (c == '\\') {
|
||||
c = in.get();
|
||||
|
||||
if (c == '\n')
|
||||
c = in.get();
|
||||
else
|
||||
core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line.");
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void read_string(std::istream& in, char* &buffer, int sz) {
|
||||
int c, pos=0;
|
||||
skip_comment_line(in);
|
||||
|
||||
while ( (c = in.get()) != EOF ) {
|
||||
if ( c == ' ' || c == '\t' || c == '\n' || c == '#')
|
||||
break;
|
||||
else
|
||||
append_char(buffer, sz, pos++, c);
|
||||
}
|
||||
append_char(buffer, sz, pos, '\0');
|
||||
}
|
||||
|
||||
void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
|
||||
char *buffer;
|
||||
int size, offset;
|
||||
int base;
|
||||
bool is_negate;
|
||||
|
||||
int c, pos = 0;
|
||||
skip_comment_line(in);
|
||||
|
||||
// read sign
|
||||
c = in.get();
|
||||
if (c == '-') {
|
||||
is_negate = true;
|
||||
c = in.get();
|
||||
} else
|
||||
is_negate = false;
|
||||
|
||||
// read base and compute digits
|
||||
if (c == '0') {
|
||||
c = in.get();
|
||||
if (c == 'b') {
|
||||
base = 2;
|
||||
size = (maxBits == 0 || maxBits > length) ? length : maxBits;
|
||||
offset = length - size;
|
||||
} else if (c == 'x') {
|
||||
base = 16;
|
||||
size = (maxBits == 0) ? length : (maxBits+3) >> 2;
|
||||
size = (size > length) ? length : size;
|
||||
offset = (length - size) << 2;
|
||||
} else {
|
||||
base = 8;
|
||||
size = (maxBits == 0) ? length : (maxBits+2) / 3;
|
||||
size = (size > length) ? length : size;
|
||||
offset = (length - size) * 3;
|
||||
in.putback(c);
|
||||
}
|
||||
} else {
|
||||
base = 10;
|
||||
size = (maxBits == 0) ? length : (int)std::ceil(maxBits*std::log(2.0)/std::log(10.0));
|
||||
size = (size > length) ? length : size;
|
||||
offset = length - size;
|
||||
in.putback(c);
|
||||
}
|
||||
|
||||
buffer = new char[size+2];
|
||||
// read digits
|
||||
for (int i=0; (i<size)&&((c=skip_backslash_new_line(in)) != EOF ); i++) {
|
||||
if (c != ' ' && c != '\t' && c != '\n')
|
||||
append_char(buffer, size, pos++, c);
|
||||
}
|
||||
if (base == 10) {
|
||||
for(int j=0; j<offset; j++)
|
||||
append_char(buffer, size, pos++, '0');
|
||||
}
|
||||
append_char(buffer, size, pos, '\0');
|
||||
|
||||
// convert string to bigint.
|
||||
if (m.set_str(buffer, base) < 0)
|
||||
core_io_error_handler("CoreIO::read_from_file()","bad big number format.");
|
||||
delete[] buffer;
|
||||
|
||||
// shift left if neccessary
|
||||
if (offset > 0 && base != 10) {
|
||||
m <<= offset;
|
||||
}
|
||||
|
||||
if (is_negate)
|
||||
negate(m);
|
||||
}
|
||||
|
||||
|
||||
void write_base_number(std::ostream& out, char* buffer, int length, int base, int charsPerLine) {
|
||||
// write big number in a format that gmp's mpz_set_str() can
|
||||
// automatically recognize with argument base = 0.
|
||||
if (base == 2)
|
||||
out << "0b";
|
||||
else if (base == 16)
|
||||
out << "0x";
|
||||
else if (base == 8)
|
||||
out << '0';
|
||||
|
||||
// write big number in charsPerLine.
|
||||
char* start, *end, c;
|
||||
for (int i=0; i<length; i += charsPerLine) {
|
||||
start = buffer + i;
|
||||
if (i + charsPerLine >= length)
|
||||
out << start;
|
||||
else {
|
||||
end = start + charsPerLine;
|
||||
c = *end;
|
||||
*end = '\0';
|
||||
|
||||
out << start << "\\\n";
|
||||
*end = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readFromFile(BigInt& z, std::istream& in, long maxLength) {
|
||||
char *buffer;
|
||||
long length;
|
||||
|
||||
// check type name whether it is Integer or not.
|
||||
buffer = new char[8];
|
||||
read_string(in, buffer, sizeof(buffer));
|
||||
if ( std::strcmp(buffer, "Integer") != 0)
|
||||
core_io_error_handler("BigInt::read_from_file()","type name expected.");
|
||||
delete[] buffer;
|
||||
|
||||
// read the bit length field.
|
||||
buffer = new char[100];
|
||||
read_string(in, buffer, sizeof(buffer));
|
||||
length = std::atol(buffer);
|
||||
delete[] buffer;
|
||||
|
||||
// read bigint
|
||||
read_base_number(in, z, length, maxLength);
|
||||
}
|
||||
|
||||
void writeToFile(const BigInt& z, std::ostream& out, int base, int charsPerLine) {
|
||||
BigInt c = abs(z);
|
||||
|
||||
// get the absoulte value string
|
||||
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
|
||||
mpz_get_str(buffer, base, c.get_mp());
|
||||
int length = std::strlen(buffer);
|
||||
|
||||
// write type name of big number and length
|
||||
//out << "# This is an experimental big number format.\n";
|
||||
out << "Integer " << length << "\n";
|
||||
|
||||
// if bigint is negative, then write an sign '-'.
|
||||
if ( sign(z) < 0 )
|
||||
out << '-';
|
||||
|
||||
write_base_number(out, buffer, length, base, charsPerLine);
|
||||
out << "\n";
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void readFromFile(BigFloat& bf, std::istream& in, long maxLength) {
|
||||
char *buffer;
|
||||
long length;
|
||||
long exponent;
|
||||
BigInt mantissa;
|
||||
|
||||
// check type name whether it is Float
|
||||
buffer = new char[6];
|
||||
read_string(in, buffer, sizeof(buffer));
|
||||
if (std::strcmp(buffer, "Float") != 0)
|
||||
core_io_error_handler("BigFloat::read_from_file()", "type name expected");
|
||||
delete[] buffer;
|
||||
|
||||
// read base (default is 16384)
|
||||
buffer = new char[8];
|
||||
read_string(in, buffer, sizeof(buffer));
|
||||
if (std::strcmp(buffer, "(16384)") != 0)
|
||||
core_io_error_handler("BigFloat::read_from_file()", "base expected");
|
||||
delete[] buffer;
|
||||
|
||||
// read the bit length field.
|
||||
buffer = new char[100];
|
||||
read_string(in, buffer, sizeof(buffer));
|
||||
length = std::atol(buffer);
|
||||
delete[] buffer;
|
||||
|
||||
// read exponent
|
||||
buffer = new char[100];
|
||||
read_string(in, buffer, sizeof(buffer));
|
||||
exponent = std::atol(buffer);
|
||||
delete[] buffer;
|
||||
|
||||
// read mantissa
|
||||
read_base_number(in, mantissa, length, maxLength);
|
||||
|
||||
// construct BigFloat
|
||||
bf = BigFloat(mantissa, 0, exponent);
|
||||
}
|
||||
|
||||
void writeToFile(const BigFloat& bf, std::ostream& out, int base, int charsPerLine) {
|
||||
BigInt c(CORE::abs(bf.m()));
|
||||
|
||||
// get the absoulte value string
|
||||
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
|
||||
mpz_get_str(buffer, base, c.get_mp());
|
||||
int length = std::strlen(buffer);
|
||||
|
||||
|
||||
// write type name, base, length
|
||||
//out << "# This is an experimental Big Float format." << std::endl;
|
||||
out << "Float (16384) " << length << std::endl;
|
||||
// write exponent
|
||||
out << bf.exp() << std::endl;
|
||||
|
||||
// write mantissa
|
||||
if ( CORE::sign(bf.m()) < 0 )
|
||||
out << '-';
|
||||
|
||||
write_base_number(out, buffer, length, base, charsPerLine);
|
||||
out << '\n';
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
/* Underconstruction ----
|
||||
void BigFloat::read_from_file2(std::istream& in, long maxLength) {
|
||||
long length = 1024;
|
||||
char *buffer;
|
||||
|
||||
// check type name whether it is Float
|
||||
buffer = new char[7];
|
||||
BigInt::read_string(in, buffer, sizeof(buffer));
|
||||
if (strcmp(buffer, "NFloat") != 0)
|
||||
core_io_error_handler("BigFloat::read_from_file2()", "type name expected");
|
||||
delete[] buffer;
|
||||
|
||||
// read base (default is 16)
|
||||
buffer = new char[5];
|
||||
BigInt::read_string(in, buffer, sizeof(buffer));
|
||||
if (strcmp(buffer, "(16)") != 0)
|
||||
core_io_error_handler("BigFloat::read_from_file2()", "base expected");
|
||||
delete[] buffer;
|
||||
|
||||
// read length field
|
||||
buffer = new char[100];
|
||||
BigInt::read_string(in, buffer, sizeof(buffer));
|
||||
|
||||
// get the length field if it is not null.
|
||||
if (buffer[0] != '\0') {
|
||||
length = atol(buffer);
|
||||
if (maxLength > 0 && length >= maxLength)
|
||||
length = maxLength;
|
||||
}
|
||||
delete[] buffer;
|
||||
|
||||
// read exponent
|
||||
buffer = new char[100];
|
||||
BigInt::read_string(in, buffer, sizeof(buffer));
|
||||
long exp16 = atol(buffer);
|
||||
delete[] buffer;
|
||||
|
||||
// read mantissa
|
||||
buffer = new char[length+2];
|
||||
//BigInt::read_base_number(in, buffer, length);
|
||||
|
||||
BigInt m16(buffer);
|
||||
delete[] buffer;
|
||||
|
||||
// convert to base CHUNK_BIT
|
||||
exp16 = exp16 - length + 1;
|
||||
if ( m16.is_negative() )
|
||||
exp16 ++;
|
||||
|
||||
long tmp_exp = exp16 * 4;
|
||||
long q = tmp_exp / CHUNK_BIT;
|
||||
long r = tmp_exp % CHUNK_BIT;
|
||||
if ( r < 0 ) {
|
||||
r += CHUNK_BIT;
|
||||
q --;
|
||||
}
|
||||
|
||||
BigInt mantissa = m16 << r;
|
||||
long exponent = q;
|
||||
|
||||
// construct BigFloat
|
||||
if (--rep->refCount == 0)
|
||||
delete rep;
|
||||
|
||||
rep = new BigFloatRep(mantissa, 0, exponent);
|
||||
rep->refCount++;
|
||||
|
||||
}
|
||||
|
||||
// write normal float
|
||||
// now it assumed to write in hex base, i.e. B=2^4=16
|
||||
// (note: our default base B=2^(CHUNK_BIT)=2^14=16384
|
||||
void BigFloat::write_to_file2(std::ostream& out, int base, int charsPerLine) {
|
||||
// convert to base 16.
|
||||
long new_base = 4; // 2^4 = 16
|
||||
long tmp_exp = (rep->exp) * CHUNK_BIT;
|
||||
long q = tmp_exp / new_base;
|
||||
long r = tmp_exp % new_base;
|
||||
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
|
||||
if ( r < 0 ) {
|
||||
r += new_base;
|
||||
q--;
|
||||
}
|
||||
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
|
||||
|
||||
BigInt m16 = (rep->m) << r;
|
||||
|
||||
int size = mpz_sizeinbase(m16.I, base) + 2;
|
||||
std::cout << "size=" << size << std::endl;
|
||||
char* buffer = new char[size];
|
||||
|
||||
int length = bigint_to_string(m16, buffer, base);
|
||||
std::cout << "length=" << length << std::endl;
|
||||
|
||||
long exp16 = q + length - 1;
|
||||
if ( m16.is_negative() )
|
||||
exp16 --;
|
||||
|
||||
// write type name, base, length
|
||||
out << "# This is an experimental Big Float format." << std::endl;
|
||||
out << "NFloat (16) " << length << std::endl;
|
||||
|
||||
// write exponent
|
||||
out << exp16 << std::endl;
|
||||
|
||||
// write mantissa
|
||||
if ( m16.is_negative() ) {
|
||||
out << '-';
|
||||
buffer ++;
|
||||
}
|
||||
|
||||
BigInt::write_base_number(out, buffer, length, base, charsPerLine);
|
||||
out << '\n';
|
||||
delete[] buffer;
|
||||
}
|
||||
*/
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/CoreIO_impl.h>
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -12,257 +12,9 @@
|
|||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
/* Auxiliary functions for C++-style input of GMP types.
|
||||
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
|
||||
#include <CGAL/CORE/Gmp.h>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <CGAL/CORE/Gmp_impl.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace CORE {
|
||||
|
||||
int
|
||||
__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
|
||||
{
|
||||
int base;
|
||||
|
||||
zero = showbase = false;
|
||||
switch (i.flags() & ios::basefield)
|
||||
{
|
||||
case ios::dec:
|
||||
base = 10;
|
||||
break;
|
||||
case ios::hex:
|
||||
base = 16;
|
||||
break;
|
||||
case ios::oct:
|
||||
base = 8;
|
||||
break;
|
||||
default:
|
||||
showbase = true; // look for initial "0" or "0x" or "0X"
|
||||
if (c == '0')
|
||||
{
|
||||
if (! i.get(c))
|
||||
c = 0; // reset or we might loop indefinitely
|
||||
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
base = 16;
|
||||
i.get(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
base = 8;
|
||||
zero = true; // if no other digit is read, the "0" counts
|
||||
}
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
break;
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
void
|
||||
__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
|
||||
{
|
||||
switch (base)
|
||||
{
|
||||
case 10:
|
||||
while (isdigit(c))
|
||||
{
|
||||
ok = true; // at least a valid digit was read
|
||||
s += c;
|
||||
if (! i.get(c))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
while (isdigit(c) && c != '8' && c != '9')
|
||||
{
|
||||
ok = true; // at least a valid digit was read
|
||||
s += c;
|
||||
if (! i.get(c))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
while (isxdigit(c))
|
||||
{
|
||||
ok = true; // at least a valid digit was read
|
||||
s += c;
|
||||
if (! i.get(c))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
istream &
|
||||
//operator>> (istream &i, mpz_ptr z)
|
||||
io_read (istream &i, mpz_ptr z)
|
||||
{
|
||||
int base;
|
||||
char c = 0;
|
||||
string s;
|
||||
bool ok = false, zero, showbase;
|
||||
|
||||
i.get(c); // start reading
|
||||
|
||||
if (i.flags() & ios::skipws) // skip initial whitespace
|
||||
while (isspace(c) && i.get(c))
|
||||
;
|
||||
|
||||
if (c == '-' || c == '+') // sign
|
||||
{
|
||||
if (c == '-') // mpz_set_str doesn't accept '+'
|
||||
s = "-";
|
||||
i.get(c);
|
||||
}
|
||||
|
||||
while (isspace(c) && i.get(c)) // skip whitespace
|
||||
;
|
||||
|
||||
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
|
||||
__gmp_istream_set_digits(s, i, c, ok, base); // read the number
|
||||
|
||||
if (i.good()) // last character read was non-numeric
|
||||
i.putback(c);
|
||||
else if (i.eof() && (ok || zero)) // stopped just before eof
|
||||
i.clear();
|
||||
|
||||
if (ok)
|
||||
mpz_set_str(z, s.c_str(), base); // extract the number
|
||||
else if (zero)
|
||||
mpz_set_ui(z, 0);
|
||||
else
|
||||
i.setstate(ios::failbit); // read failed
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
istream &
|
||||
//operator>> (istream &i, mpq_ptr q)
|
||||
io_read (istream &i, mpq_ptr q)
|
||||
{
|
||||
int base;
|
||||
char c = 0;
|
||||
string s;
|
||||
bool ok = false, zero, showbase;
|
||||
|
||||
i.get(c); // start reading
|
||||
|
||||
if (i.flags() & ios::skipws) // skip initial whitespace
|
||||
while (isspace(c) && i.get(c))
|
||||
;
|
||||
|
||||
if (c == '-' || c == '+') // sign
|
||||
{
|
||||
if (c == '-')
|
||||
s = "-";
|
||||
i.get(c);
|
||||
}
|
||||
|
||||
while (isspace(c) && i.get(c)) // skip whitespace
|
||||
;
|
||||
|
||||
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
|
||||
__gmp_istream_set_digits(s, i, c, ok, base); // read the numerator
|
||||
|
||||
if (! ok && zero) // the only digit read was "0"
|
||||
{
|
||||
base = 10;
|
||||
s += '0';
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (i.flags() & ios::skipws)
|
||||
while (isspace(c) && i.get(c)) // skip whitespace
|
||||
;
|
||||
|
||||
if (c == '/') // there's a denominator
|
||||
{
|
||||
bool zero2 = false;
|
||||
int base2 = base;
|
||||
|
||||
s += '/';
|
||||
ok = false; // denominator is mandatory
|
||||
i.get(c);
|
||||
|
||||
while (isspace(c) && i.get(c)) // skip whitespace
|
||||
;
|
||||
|
||||
if (showbase) // check base of denominator
|
||||
base2 = __gmp_istream_set_base(i, c, zero2, showbase);
|
||||
|
||||
if (base2 == base || base2 == 10) // read the denominator
|
||||
__gmp_istream_set_digits(s, i, c, ok, base);
|
||||
|
||||
if (! ok && zero2) // the only digit read was "0"
|
||||
{ // denominator is 0, but that's your business
|
||||
s += '0';
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (i.good()) // last character read was non-numeric
|
||||
i.putback(c);
|
||||
else if (i.eof() && ok) // stopped just before eof
|
||||
i.clear();
|
||||
|
||||
if (ok)
|
||||
mpq_set_str(q, s.c_str(), base); // extract the number
|
||||
else
|
||||
i.setstate(ios::failbit); // read failed
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
ostream&
|
||||
//operator<< (ostream &o, mpz_srcptr z)
|
||||
io_write (ostream &o, mpz_srcptr z)
|
||||
{
|
||||
char *str = new char [mpz_sizeinbase(z,10) + 2];
|
||||
str = mpz_get_str(str, 10, z);
|
||||
o << str ;
|
||||
delete[] str;
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream&
|
||||
//operator<< (ostream &o, mpq_srcptr q)
|
||||
io_write (ostream &o, mpq_srcptr q)
|
||||
{
|
||||
// size according to GMP documentation
|
||||
char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) +
|
||||
mpz_sizeinbase (mpq_denref(q), 10) + 3];
|
||||
str = mpq_get_str(str, 10, q);
|
||||
o << str ;
|
||||
delete[] str;
|
||||
return o;
|
||||
}
|
||||
|
||||
} //namespace CORE
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -35,242 +35,9 @@
|
|||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
|
||||
#include <CGAL/CORE/Real.h>
|
||||
#include <CGAL/CORE/Real_impl.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
const Real& Real::getZero() {
|
||||
static Real Zero(0);
|
||||
return Zero;
|
||||
}
|
||||
|
||||
BigInt floor(const Real& r, Real &sub) {
|
||||
BigInt f = r.approx(CORE_INFTY, 2).BigIntValue();
|
||||
sub = r-f;
|
||||
// Adjustment
|
||||
if (sub<0)
|
||||
++sub, --f;
|
||||
if (sub>=1)
|
||||
--sub, ++f;
|
||||
assert(sub >=0 && sub<1);
|
||||
return f;
|
||||
}
|
||||
|
||||
// pow(r,n) and power(r, n) are the same function
|
||||
//
|
||||
Real pow(const Real& r, unsigned long n) {
|
||||
if (n == 0)
|
||||
return Real(1);
|
||||
else if (n == 1)
|
||||
return r;
|
||||
else {
|
||||
Real x = r;
|
||||
while ((n % 2) == 0) { // n is even
|
||||
x *= x;
|
||||
n >>= 1;
|
||||
}
|
||||
Real u = x;
|
||||
while (true) {
|
||||
n >>= 1;
|
||||
if (n == 0)
|
||||
return u;
|
||||
x *= x;
|
||||
if ((n % 2) == 1) // n is odd
|
||||
u *= x;
|
||||
}
|
||||
//return u; // unreachable
|
||||
}
|
||||
}//pow
|
||||
|
||||
extern BigInt FiveTo(unsigned long exp);
|
||||
|
||||
// Construct Real from String
|
||||
// Note:
|
||||
// -- Zilin Du: 06/03/2003
|
||||
// -- Original it is the code for Real's constructor for "const char*".
|
||||
// I change it to a function so that two constrcutors can share the code.
|
||||
// now it is private and no default value.
|
||||
//
|
||||
// --Default value of the argument "prec" is defInputDigits
|
||||
// --If prec is CORE_posInfty, then the input is
|
||||
// read in exactly. Otherwise, we convert to a RealBigFloat
|
||||
// with absolute error at most 10^{-prec}
|
||||
|
||||
// Constructor Real( char *str, extLong& prec)
|
||||
// is very similar to
|
||||
// BigFloatRep::fromString( char *str, extLong& prec);
|
||||
// Differences:
|
||||
// In BigFloat(str, prec), the value of prec cannot be infinity, and
|
||||
// it defaults to defBigFloatInputDigits;
|
||||
// In Real(str, prec), the value of prec is allowed to be infinity, and
|
||||
// it defaults to defInputDigits.
|
||||
//
|
||||
// Why do we have the two versions? It allows us to use the BigFloat class
|
||||
// directly, without relying on Real class.
|
||||
|
||||
void Real::constructFromString(const char *str, const extLong& prec )
|
||||
// NOTE: prec defaults to defInputDigits (see Real.h)
|
||||
{
|
||||
// 8/8/01, Chee and Zilin: add a new rational string format:
|
||||
// this format is indicated by the presence of a slash "/"
|
||||
// Moreover, the value of prec is ignored (basically
|
||||
// assumed to be infinity).
|
||||
|
||||
if (std::strchr(str, '/') != NULL) { // this is a rational number
|
||||
rep = new RealBigRat(BigRat(str));
|
||||
return;
|
||||
}
|
||||
|
||||
const char *e = std::strchr(str, 'e');
|
||||
int dot = 0;
|
||||
long e10 = 0;
|
||||
if (e != NULL)
|
||||
e10 = std::atol(e+1); // e10 is decimal precision of the input string
|
||||
// i.e., input is A/10^{e10}.
|
||||
else {
|
||||
e = str + std::strlen(str);
|
||||
#ifdef CORE_DEBUG
|
||||
assert(*e == '\0');
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *p = str;
|
||||
if (*p == '-' || *p == '+')
|
||||
p++;
|
||||
BigInt m(0);
|
||||
|
||||
for (; p < e; p++) {
|
||||
if (*p == '.') {
|
||||
dot = 1;
|
||||
continue;
|
||||
}
|
||||
m = m * 10 + (*p - '0');
|
||||
if (dot)
|
||||
e10--;
|
||||
}
|
||||
|
||||
long t = (e10 < 0) ? -e10 : e10;
|
||||
BigInt one(1);
|
||||
BigInt ten = FiveTo(t) * (one << static_cast<unsigned long>(t));
|
||||
if (*str == '-')
|
||||
m = -m;
|
||||
if (e10 >= 0) {
|
||||
// convert exactly from integer numbers
|
||||
m *= ten;
|
||||
rep = new RealBigInt(m);
|
||||
} else { // e10 < 0, fractional numbers
|
||||
// HERE IS WHERE WE USE THE SYSTEM CONSTANT
|
||||
// defInputDigits
|
||||
// Note: defInputDigits should be at least log_2(10).
|
||||
// We default defInputDigits to 4.
|
||||
//std::cout << "(m,ten)=" << m << "," << ten << std::endl;
|
||||
BigRat r(m, ten);
|
||||
if (prec.isInfty()) { // convert exactly! to a big rational
|
||||
rep = new RealBigRat(r);
|
||||
} else {
|
||||
// convert approximately, to a BigFloat within the
|
||||
// specified precision:
|
||||
// BigFloat bf(r, CORE_posInfty, prec * lgTenM) ;
|
||||
BigFloat bf(r, CORE_posInfty, prec * 4) ;
|
||||
rep = new RealBigFloat(bf);
|
||||
}
|
||||
}
|
||||
}// Real(str, prec)
|
||||
|
||||
// The operator >>(i,x) calls the constructor Real(char*)
|
||||
std::istream& operator >>(std::istream& i, Real& x) {
|
||||
int size = 20;
|
||||
char *str = new char[size];
|
||||
char *p = str;
|
||||
char c;
|
||||
int d = 0, e = 0, s = 0;
|
||||
// int done = 0;
|
||||
|
||||
// Chen Li: fixed a bug, the original statement is
|
||||
// for (i.get(c); c == ' '; i.get(c));
|
||||
// use isspace instead of testing c == ' ', since it must also
|
||||
// skip tab, catridge/return, etc.
|
||||
// Change to:
|
||||
// int status;
|
||||
do {
|
||||
i.get(c);
|
||||
} while (!i.eof() && isspace(c)); /* loop if met end-of-file, or
|
||||
char read in is white-space. */
|
||||
// Chen Li,
|
||||
// original "if (c == EOF) ..." is unsafe since c is of char type and
|
||||
// EOF is of int tyep with a negative value -1
|
||||
|
||||
if (i.eof()) {
|
||||
i.clear(std::ios::eofbit | std::ios::failbit);
|
||||
delete [] str;
|
||||
return i;
|
||||
}
|
||||
|
||||
// the current content in "c" should be the first non-whitespace char
|
||||
if (c == '-' || c == '+') {
|
||||
*p++ = c;
|
||||
i.get(c);
|
||||
}
|
||||
|
||||
for (; isdigit(c) || (!d && c=='.') ||
|
||||
(!e && c=='e') || (!s && (c=='-' || c=='+')); i.get(c)) {
|
||||
if (!i) break;
|
||||
if (!e && (c == '-' || c == '+'))
|
||||
break;
|
||||
// Chen Li: put one more rule to prohibite input like
|
||||
// xxxx.xxxe+xxx.xxx:
|
||||
if (e && (c == '.'))
|
||||
break;
|
||||
if (p - str == size) {
|
||||
char *t = str;
|
||||
str = new char[size*2];
|
||||
std::memcpy(str, t, size);
|
||||
delete [] t;
|
||||
p = str + size;
|
||||
size *= 2;
|
||||
}
|
||||
#ifdef CORE_DEBUG
|
||||
assert((p-str) < size);
|
||||
#endif
|
||||
|
||||
*p++ = c;
|
||||
if (c == '.')
|
||||
d = 1;
|
||||
// Chen Li: fix a bug -- the sign of exponent can not happen before
|
||||
// the character "e" appears! It must follow the "e' actually.
|
||||
// if (e || c == '-' || c == '+') s = 1;
|
||||
if (e)
|
||||
s = 1;
|
||||
if (c == 'e')
|
||||
e = 1;
|
||||
}
|
||||
|
||||
if (!i && !i.eof()) {
|
||||
delete [] str;
|
||||
return i;
|
||||
}
|
||||
// chenli: make sure that the p is still in the range
|
||||
if (p - str >= size) {
|
||||
int len = p - str;
|
||||
char *t = str;
|
||||
str = new char[len + 1];
|
||||
std::memcpy(str, t, len);
|
||||
delete [] t;
|
||||
p = str + len;
|
||||
}
|
||||
|
||||
#ifdef CORE_DEBUG
|
||||
assert(p - str < size);
|
||||
#endif
|
||||
|
||||
*p = '\0';
|
||||
i.putback(c);
|
||||
i.clear();
|
||||
// old: x = Real(str, i.precision()); // use precision of input stream.
|
||||
x = Real(str); // default precision = defInputDigits
|
||||
delete [] str;
|
||||
return i;
|
||||
}//operator >> (std::istream&, Real&)
|
||||
|
||||
} //namespace CORE
|
||||
|
|
|
|||
|
|
@ -39,157 +39,9 @@
|
|||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef CGAL_HEADER_ONLY
|
||||
|
||||
#include <CGAL/CORE/extLong.h>
|
||||
#include <CGAL/CORE/extLong_impl.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
const extLong& extLong::getNaNLong() {
|
||||
static extLong NaNLong(true);
|
||||
return NaNLong;
|
||||
}
|
||||
|
||||
const extLong& extLong::getPosInfty() {
|
||||
static extLong posInfty(EXTLONG_MAX);
|
||||
return posInfty;
|
||||
}
|
||||
|
||||
const extLong& extLong::getNegInfty() {
|
||||
static extLong negInfty(EXTLONG_MIN);
|
||||
return negInfty;
|
||||
}
|
||||
|
||||
void extLong::add(extLong& z, long x, long y) {
|
||||
if (x > 0 && y > 0 && x >= EXTLONG_MAX - y) {
|
||||
z.val = EXTLONG_MAX;
|
||||
z.flag = 1;
|
||||
} else if (x < 0 && y < 0 && x <= EXTLONG_MIN - y) {
|
||||
z.val = EXTLONG_MIN;
|
||||
z.flag = -1;
|
||||
} else {
|
||||
z.val = x + y;
|
||||
z.flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// arithmetic and assignment operators
|
||||
extLong& extLong::operator+= (const extLong& y) {
|
||||
if (flag == 2 || y.flag == 2 || (flag * y.flag < 0)) {
|
||||
#ifdef CORE_DEBUG
|
||||
if (flag * y.flag < 0) //want a message at the first creation of NaN
|
||||
core_error("extLong NaN Error in addition.", __FILE__, __LINE__, false);
|
||||
#endif
|
||||
|
||||
*this = CORE_NaNLong;
|
||||
} else if (flag == 1 || y.flag == 1) { // one of them is +Inf
|
||||
*this = CORE_posInfty;
|
||||
} else if (flag == -1 || y.flag == -1) { // one of them is -Inf
|
||||
*this = CORE_negInfty;
|
||||
} else { // x and y are normal now
|
||||
add(*this, val, y.val);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
extLong& extLong::operator-= (const extLong& y) {
|
||||
if (flag == 2 || y.flag == 2 || (flag * y.flag > 0)) {
|
||||
#ifdef CORE_DEBUG
|
||||
if (flag * y.flag > 0) //want a message at the first creation of NaN
|
||||
core_error("extLong NaN Error in subtraction.", __FILE__, __LINE__, false);
|
||||
#endif
|
||||
|
||||
*this = CORE_NaNLong;
|
||||
} else if (flag == 1 || y.flag == -1) {
|
||||
*this = CORE_posInfty;
|
||||
} else if (flag == -1 || y.flag == 1) {
|
||||
*this = CORE_negInfty;
|
||||
} else {
|
||||
add(*this, val, -y.val);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
extLong& extLong::operator*= (const extLong& y) {
|
||||
if (flag == 2 || y.flag == 2) {
|
||||
*this = CORE_NaNLong;
|
||||
} else if ((flag != 0) || (y.flag != 0)) {
|
||||
if (sign() * y.sign() > 0)
|
||||
*this = CORE_posInfty;
|
||||
else
|
||||
*this = CORE_negInfty;
|
||||
} else { // flag == 0 and y.flag == 0
|
||||
double d = double(val) * double(y.val);
|
||||
long p = val * y.val;
|
||||
if (std::fabs(d - p) <= std::fabs(d) * relEps) {
|
||||
val = p;
|
||||
flag = 0;
|
||||
} else if (d > EXTLONG_MAX) {
|
||||
*this = CORE_posInfty;
|
||||
} else if (d < EXTLONG_MIN) {
|
||||
*this = CORE_negInfty;
|
||||
} else {
|
||||
#ifdef CORE_DEBUG
|
||||
core_error("extLong NaN Error in multiplication.",__FILE__,__LINE__,false);
|
||||
#endif
|
||||
*this = CORE_NaNLong;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
extLong& extLong::operator/= (const extLong& y) {
|
||||
if (flag==2 || y.flag==2 || ((flag != 0) && (y.flag != 0)) || (y.val == 0)) {
|
||||
#ifdef CORE_DEBUG
|
||||
if (y.val == 0)
|
||||
core_error("extLong NaN Error, Divide by Zero.", __FILE__, __LINE__, false);
|
||||
else if ((flag !=0) && (y.flag !=0))
|
||||
core_error("extLong NaN Error, +/-Inf/Inf.", __FILE__, __LINE__, false);
|
||||
#endif
|
||||
|
||||
*this = CORE_NaNLong;
|
||||
} else if ((flag != 0) || (y.flag != 0)) { // y.flag == 0 now and y != 0
|
||||
if (sign() * y.sign() > 0)
|
||||
*this = CORE_posInfty;
|
||||
else
|
||||
*this = CORE_negInfty;
|
||||
} else { // flag == 0 and y.flag == 0
|
||||
val /= y.val; // no overflow in divisions
|
||||
flag = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// unary minus
|
||||
extLong extLong::operator- () const {
|
||||
if (flag == 0)
|
||||
return extLong(-val);
|
||||
else if (flag == 1)
|
||||
return CORE_negInfty;
|
||||
else if (flag == -1)
|
||||
return CORE_posInfty;
|
||||
else // NaN
|
||||
return CORE_NaNLong;
|
||||
}
|
||||
|
||||
// sign
|
||||
// You should check "flag" before calling this, otherwise
|
||||
// you cannot interprete the returned value!
|
||||
int extLong::sign() const {
|
||||
if (flag == 2)
|
||||
core_error("NaN Sign can not be determined!", __FILE__, __LINE__, false);
|
||||
return ((val == 0) ? 0 : ((val > 0) ? 1 : -1));
|
||||
}
|
||||
|
||||
// stream operators
|
||||
std::ostream& operator<< (std::ostream& o, const extLong& x) {
|
||||
if (x.flag == 1)
|
||||
o << " infty ";
|
||||
else if (x.flag == - 1)
|
||||
o << " tiny ";
|
||||
else if (x.flag == 2)
|
||||
o << " NaN ";
|
||||
else
|
||||
o << x.val;
|
||||
return o;
|
||||
}
|
||||
|
||||
} //namespace CORE
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ namespace internal{
|
|||
|
||||
CORE::BigFloat
|
||||
inline
|
||||
round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){
|
||||
round(const CORE::BigFloat& x, long rel_prec = CORE::get_static_defRelPrec().toLong() ){
|
||||
CGAL_postcondition(rel_prec >= 0);
|
||||
|
||||
// since there is not rel prec defined if Zero_in(x)
|
||||
|
|
@ -344,9 +344,9 @@ public:
|
|||
typedef long result_type;
|
||||
|
||||
long operator() ( long prec ) const {
|
||||
long result = ::CORE::defRelPrec.toLong();
|
||||
::CORE::defRelPrec = prec;
|
||||
::CORE::defBFdivRelPrec = prec;
|
||||
long result = ::CORE::get_static_defRelPrec().toLong();
|
||||
::CORE::get_static_defRelPrec() = prec;
|
||||
::CORE::get_static_defBFdivRelPrec() = prec;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
|
@ -356,7 +356,7 @@ public:
|
|||
typedef long result_type;
|
||||
|
||||
long operator() () const {
|
||||
return ::CORE::defRelPrec.toLong();
|
||||
return ::CORE::get_static_defRelPrec().toLong();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -378,17 +378,19 @@ template <> class Algebraic_structure_traits< CORE::BigFloat >
|
|||
: public std::unary_function< Type, Type > {
|
||||
public:
|
||||
Type operator()( const Type& x ) const {
|
||||
// What I want is a sqrt computed with ::CORE::defRelPrec bits.
|
||||
// What I want is a sqrt computed with
|
||||
// ::CORE::get_static_defRelPrec() bits.
|
||||
// And not ::CORE::defBFsqrtAbsPrec as CORE does.
|
||||
|
||||
CGAL_precondition(::CORE::defRelPrec.toLong() > 0);
|
||||
CGAL_precondition(::CORE::get_static_defRelPrec().toLong() > 0);
|
||||
CGAL_precondition(x > 0);
|
||||
|
||||
Type a = CGAL::internal::round(x, ::CORE::defRelPrec.toLong()*2);
|
||||
Type a = CGAL::internal::round(
|
||||
x, ::CORE::get_static_defRelPrec().toLong()*2);
|
||||
CGAL_postcondition(a > 0);
|
||||
|
||||
Type tmp1 =
|
||||
CORE::BigFloat(a.m(),0,0).sqrt(::CORE::defRelPrec.toLong());
|
||||
Type tmp1 = CORE::BigFloat(
|
||||
a.m(),0,0).sqrt(::CORE::get_static_defRelPrec().toLong());
|
||||
Type err =
|
||||
Type(0,long(std::sqrt(double(a.err()))),0)
|
||||
* CORE::BigFloat::exp2(a.exp()*7);
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigInt>{
|
|||
Type operator()(const CORE::BigFloat& x) const { return x;}
|
||||
Type operator()(const ::CORE::BigInt x) const {
|
||||
CORE::BigFloat result;
|
||||
result.approx(x,CORE::defRelPrec.toLong(),LONG_MAX);
|
||||
result.approx(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX);
|
||||
// Do not use MakeFloorExact as it changes the Bigfloat
|
||||
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
|
||||
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
|
||||
|
|
@ -104,7 +104,7 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigRat>{
|
|||
Type operator()(const CORE::BigFloat& x) const { return x;}
|
||||
Type operator()(const ::CORE::BigRat x) const {
|
||||
|
||||
CORE::BigFloat result(x,CORE::defRelPrec.toLong(),LONG_MAX);
|
||||
CORE::BigFloat result(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX);
|
||||
// Do not use MakeFloorExact as it changes the Bigfloat
|
||||
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
|
||||
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
|
||||
|
|
@ -123,7 +123,7 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::Expr>{
|
|||
typedef Type result_type;
|
||||
Type operator()(const CORE::BigFloat& x) const { return x;}
|
||||
Type operator()(const ::CORE::Expr x) const {
|
||||
CORE::BigFloat result(x, CORE::defRelPrec.toLong(),LONG_MAX);
|
||||
CORE::BigFloat result(x, CORE::get_static_defRelPrec().toLong(),LONG_MAX);
|
||||
// Do not use MakeFloorExact as it changes the Bigfloat
|
||||
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
|
||||
CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
|
||||
|
|
|
|||
|
|
@ -606,64 +606,6 @@ protected:
|
|||
TLS_thread_uint_ids m_tls_thread_ids;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// class Spatial_lock_grid_3<Tag_non_blocking_with_mutexes>
|
||||
// Note: undocumented, for testing only...
|
||||
//*****************************************************************************
|
||||
|
||||
template <>
|
||||
class Spatial_lock_grid_3<Tag_non_blocking_with_mutexes>
|
||||
: public Spatial_lock_grid_base_3<
|
||||
Spatial_lock_grid_3<Tag_non_blocking_with_mutexes> >
|
||||
{
|
||||
typedef Spatial_lock_grid_base_3<
|
||||
Spatial_lock_grid_3<Tag_non_blocking_with_mutexes> > Base;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
Spatial_lock_grid_3(const Bbox_3 &bbox, int num_grid_cells_per_axis)
|
||||
: Base(bbox, num_grid_cells_per_axis)
|
||||
{
|
||||
int num_cells =
|
||||
num_grid_cells_per_axis*num_grid_cells_per_axis*num_grid_cells_per_axis;
|
||||
m_grid.resize(num_cells);
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~Spatial_lock_grid_3()
|
||||
{
|
||||
}
|
||||
|
||||
bool is_cell_locked_impl(int cell_index)
|
||||
{
|
||||
bool locked = m_grid[cell_index].try_lock();
|
||||
if (locked)
|
||||
m_grid[cell_index].unlock();
|
||||
return !locked;
|
||||
}
|
||||
|
||||
template <bool no_spin>
|
||||
bool try_lock_cell_impl(int cell_index)
|
||||
{
|
||||
bool success = m_grid[cell_index].try_lock();
|
||||
if (success)
|
||||
{
|
||||
get_thread_local_grid()[cell_index] = true;
|
||||
m_tls_locked_cells.local().push_back(cell_index);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void unlock_cell_impl(int cell_index)
|
||||
{
|
||||
m_grid[cell_index].unlock();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<tbb::recursive_mutex> m_grid;
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#else // !CGAL_LINKED_WITH_TBB
|
||||
|
|
|
|||
Loading…
Reference in New Issue