mirror of https://github.com/CGAL/cgal
Forgot 2 *_impl.h files
This commit is contained in:
parent
d0e0c44f9d
commit
f532cbc013
|
|
@ -0,0 +1,291 @@
|
|||
/****************************************************************************
|
||||
* 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: Real.cpp
|
||||
* Synopsis: The Real class is a superclass for all the number
|
||||
* systems in the Core Library (int, long, float, double,
|
||||
* BigInt, BigRat, BigFloat, etc)
|
||||
*
|
||||
* Written by
|
||||
* Koji Ouchi <ouchi@simulation.nyu.edu>
|
||||
* Chee Yap <yap@cs.nyu.edu>
|
||||
* Chen Li <chenli@cs.nyu.edu>
|
||||
* Zilin Du <zilin@cs.nyu.edu>
|
||||
* Sylvain Pion <pion@cs.nyu.edu>
|
||||
*
|
||||
* WWW URL: http://cs.nyu.edu/exact/
|
||||
* Email: exact@cs.nyu.edu
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#define CGAL_INLINE_FUNCTION inline
|
||||
#else
|
||||
#define CGAL_INLINE_FUNCTION
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <CGAL/CORE/Real.h>
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/BigFloat.h> // for FiveTo
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
const Real& Real::getZero() {
|
||||
static Real Zero(0);
|
||||
return Zero;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
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
|
||||
//
|
||||
CGAL_INLINE_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 get_static_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.
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
void Real::constructFromString(const char *str, const extLong& prec )
|
||||
// NOTE: prec defaults to get_static_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
|
||||
// get_static_defInputDigits()
|
||||
// Note: get_static_defInputDigits() should be at least log_2(10).
|
||||
// We default get_static_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*)
|
||||
CGAL_INLINE_FUNCTION
|
||||
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 = get_static_defInputDigits()
|
||||
delete [] str;
|
||||
return i;
|
||||
}//operator >> (std::istream&, Real&)
|
||||
|
||||
} //namespace CORE
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
/****************************************************************************
|
||||
* 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: extLong.cpp
|
||||
* Synopsis:
|
||||
* The class extLong is basically a wrapper around the machine
|
||||
* type long. It is an important class to provide several
|
||||
* additional facilities to detect overflows and undefined values.
|
||||
* Future development includes extensions to level arithmetic
|
||||
* (i.e., if a number overflows level i, we will go to level i+1).
|
||||
* Level i representation of a number n is just i iterations
|
||||
* of log_2 applied to n.
|
||||
*
|
||||
* Written by
|
||||
* Chee Yap <yap@cs.nyu.edu>
|
||||
* Chen Li <chenli@cs.nyu.edu>
|
||||
* Zilin Du <zilin@cs.nyu.edu>
|
||||
* Sylvain Pion <pion@cs.nyu.edu>
|
||||
*
|
||||
* WWW URL: http://cs.nyu.edu/exact/
|
||||
* Email: exact@cs.nyu.edu
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#define CGAL_INLINE_FUNCTION inline
|
||||
#else
|
||||
#define CGAL_INLINE_FUNCTION
|
||||
#endif
|
||||
|
||||
#include <CGAL/CORE/extLong.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
const extLong& extLong::getNaNLong() {
|
||||
static extLong NaNLong(true);
|
||||
return NaNLong;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
const extLong& extLong::getPosInfty() {
|
||||
static extLong posInfty(EXTLONG_MAX);
|
||||
return posInfty;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
const extLong& extLong::getNegInfty() {
|
||||
static extLong negInfty(EXTLONG_MIN);
|
||||
return negInfty;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
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
|
||||
CGAL_INLINE_FUNCTION
|
||||
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;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
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;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
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;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
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
|
||||
CGAL_INLINE_FUNCTION
|
||||
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!
|
||||
CGAL_INLINE_FUNCTION
|
||||
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
|
||||
CGAL_INLINE_FUNCTION
|
||||
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
|
||||
Loading…
Reference in New Issue