Forgot 2 *_impl.h files

This commit is contained in:
Clement Jamin 2014-12-15 21:57:51 +01:00
parent d0e0c44f9d
commit f532cbc013
2 changed files with 503 additions and 0 deletions

View File

@ -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

View File

@ -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