WIP: Replace CORE::BigInt and BigRat with the boost::mp classes. Just typedef

This commit is contained in:
Andreas Fabri 2022-10-25 15:32:26 +01:00
parent b32d1f0023
commit e98692d8b8
16 changed files with 294 additions and 50 deletions

View File

@ -54,7 +54,7 @@ public:
};
#if 0
template <>
struct Get_arithmetic_kernel<CORE::BigInt>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
@ -63,6 +63,8 @@ template <>
struct Get_arithmetic_kernel<CORE::BigRat>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
};
#endif
template <>
struct Get_arithmetic_kernel<CORE::Expr>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
@ -74,6 +76,7 @@ struct Get_arithmetic_kernel<CORE::BigFloat>{
} //namespace CGAL
#endif // CGAL_USE_CORE
#endif // CGAL_CORE_ARITHMETIC_KERNEL_H

View File

@ -59,7 +59,7 @@ public:
/// constructor for <tt>const char* </tt>(default base = 10)
BigFloat(const char* s) : RCBigFloat(new BigFloatRep(s)) {}
/// constructor for <tt>std::string</tt>(default base = 10)
BigFloat(const std::string& s) : RCBigFloat(new BigFloatRep(s)) {}
BigFloat(const std::string& s) : RCBigFloat(new BigFloatRep(s.c_str())) {}
/// constructor for <tt>int</tt> and <tt>long</tt>
// This is a hack because in Sturm, we need to approximate any
@ -614,11 +614,23 @@ inline BigFloat gcd(const BigFloat& a, const BigFloat& b) {
//mpz_tdiv_qr(q.get_mp(), r.get_mp(), a.get_mp(), b.get_mp());
//}//
/* AF
// constructor BigRat from BigFloat
inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){
*this = f.BigRatValue();
}
*/
double doubleValue(const BigFloat& bf)
{
return bf.doubleValue();
}
long longValue(const BigFloat& bf)
{
return bf.longValue();
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY

View File

@ -870,7 +870,7 @@ BigFloatRep::toDecimal(unsigned int width, bool Scientific) const {
M <<= e2; // M = x * 2^(e2)
}
std::string decRep = M.get_str();
std::string decRep = M.convert_to<std::string>();
// Determine the "significant part" of this string, i.e. the part which
// is guaranteed to be correct in the presence of error,
// except that the last digit which might be subject to +/- 1.

View File

@ -30,6 +30,176 @@
#include <CGAL/CORE/MemoryPool.h>
#include <string>
#if 1
namespace CORE {
#ifdef CGAL_CORE_USE_GMP_BACKEND
typedef boost::multiprecision::mpz_int BigInt;
#else
typedef boost::multiprecision::cpp_int BigInt;
#endif
inline int cmp(const BigInt& x, const BigInt& y) {
return x.compare(y);
}
int set_str(BigInt& a, const char* s) {
// AF makeCopy();
a = BigInt(s);
return 0; // should be -1 if not correct in the base (we ignore)
}
/// longValue
inline long longValue(const BigInt& a) {
return a.convert_to<long>();;
}
/// doubleValue
inline double doubleValue(const BigInt& a) {
return a.convert_to<double>();;
}
/// isEven
inline bool isEven(const BigInt& z) {
return bit_test(z,0) == 0;
}
/// isOdd
inline bool isOdd(const BigInt& z) {
return bit_test(z,0) == 1;
}
inline bool isDivisible(const BigInt& x, const BigInt& y) {
BigInt q, r;
divide_qr(x, y, q, r);
return r.is_zero();
}
inline bool isDivisible(int x, int y) {
return x % y == 0;
}
inline bool isDivisible(long x, long y) {
return x % y == 0;
}
/// get exponent of power 2
inline unsigned long getBinExpo(const BigInt& z) {
if (z.is_zero()) {
return (std::numeric_limits<unsigned long>::max)();
}
return lsb(abs(z));
}
// bit length
inline int bitLength(const BigInt& a) {
if (a.is_zero()) {
return 0;
}
return msb(abs(a))+1;
}
/// floorLg -- floor of log_2(a)
/** Convention: a=0, floorLg(a) returns -1.
* This makes sense for integer a.
*/
inline long floorLg(const BigInt& a) {
return (sign(a) == 0) ? (-1) : (bitLength(a)-1);
}
/// div_rem
inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) {
// AF q.makeCopy();
// AF r.makeCopy();
divide_qr(a, b, q, r);
}
/// ulongValue
inline unsigned long ulongValue(const BigInt& a) {
assert(a >= BigInt(0));
return a.convert_to<unsigned long>();
}
/// exact div
inline void divexact(BigInt& z, const BigInt& x, const BigInt& y) {
// AF z.makeCopy();
BigInt r;
divide_qr(x, y, z, r ); // was void mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d) Is this faster?
assert(r.is_zero());
}
// Chee (1/12/2004) The definition of div_exact(x,y) next
// ensure that in Polynomials<NT> works with both NT=BigInt and NT=int:
inline BigInt div_exact(const BigInt& x, const BigInt& y) {
BigInt z; // precodition: isDivisible(x,y)
divexact(z, x, y); // z is set to x/y;
return z;
}
inline int div_exact(int x, int y) {
return x/y; // precondition: isDivisible(x,y)
}
inline long div_exact(long x, long y) {
return x/y; // precondition: isDivisible(x,y)
}
/// ceilLg -- ceiling of log_2(a) where a=BigInt, int or long
/** Convention: a=0, ceilLg(a) returns -1.
* This makes sense for integer a.
*/
inline long ceilLg(const BigInt& a) {
if (sign(a) == 0)
return -1;
unsigned long len = bitLength(a);
return (lsb(abs(a)) == len - 1) ? (len - 1) : len;
}
inline long ceilLg(long a) { // need this for Polynomial<long>
return ceilLg(BigInt(a));
}
inline long ceilLg(int a) { // need this for Polynomial<int>
return ceilLg(BigInt(a));
}
/// negate
inline void negate(BigInt& a) {
// AF a.makeCopy();
a= - a;
}
/// get exponent of power k
inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long uk) {
BigInt k(uk), q, r;
e = 0;
m = z;
// AF m.makeCopy();
for(;;) {
divide_qr(m, k, q, r);
if (!r.is_zero()) break;
m = q;
++e;
}
}
inline void power(BigInt& c, const BigInt& a, unsigned long ul) {
// AF c.makeCopy();
c = pow(a, ul);
}
} // namespace CORE
#else
namespace CORE {
#ifdef CGAL_CORE_USE_GMP_BACKEND
@ -55,11 +225,7 @@ public:
: mp(c)
{}
BigIntRep(const char* s, int base=0)
: mp(s)
{ assert(base == 0); }
BigIntRep(const std::string& s, int base=0)
BigIntRep(const std::string& s)
: mp(s)
{}
@ -118,10 +284,9 @@ public:
BigInt(float x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>double</tt>
BigInt(double x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>const char*</tt> with base
BigInt(const char* s, int base=0) : RCBigInt(new BigIntRep(s, base)) {}
/// constructor for <tt>std::string</tt> with base
BigInt(const std::string& s, int base=0) : RCBigInt(new BigIntRep(s, base)) {}
/// constructor for <tt>std::string</tt>
BigInt(const std::string& s) : RCBigInt(new BigIntRep(s)) {}
/// constructor for <tt>mpz_srcptr</tt>
// explicit BigInt(mpz_srcptr z) : RCBigInt(new BigIntRep(z)) {}
@ -254,13 +419,13 @@ public:
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt>
int set_str(const char* s, int base = 0) {
int set_str(const char* s) {
makeCopy();
get_mp() = Z(s);
return 0; // should be -1 if not correct in the base (we ignore)
}
/// convert to <tt>std::string</tt>
std::string get_str(int base = 10) const {
std::string get_str() const {
return get_mp().convert_to<std::string>();
}
//@}
@ -443,7 +608,7 @@ inline double doubleValue(const BigInt& a) {
void readFromFile(BigInt& z, std::istream& in, long maxLength = 0);
/// write to file
void writeToFile(const BigInt& z, std::ostream& in, int base=10, int charsPerLine=80);
void writeToFile(const BigInt& z, std::ostream& in, int charsPerLine=80);
//@}
*/
@ -483,8 +648,8 @@ inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long uk) {
/// divisible(x,y) = "x | y"
inline bool isDivisible(const BigInt& x, const BigInt& y) {
BigInt z, r;
divide_qr(x.get_mp(), y.get_mp(), z.get_mp(), r.get_mp());
BigInt q, r;
divide_qr(x.get_mp(), y.get_mp(), q.get_mp(), r.get_mp());
return r.get_mp().is_zero();
}
@ -538,7 +703,7 @@ inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) {
/// power
inline void power(BigInt& c, const BigInt& a, unsigned long ul) {
c.makeCopy();
c.get_mp() = pow(a.get_mp(), ul);
//c.get_mp() = pow(a.get_mp(), ul);
}
// pow
@ -553,7 +718,7 @@ inline int bitLength(const BigInt& a) {
if (a.get_mp().is_zero()) {
return 0;
}
return msb(abs(a.get_mp()))+1; /// AF todo was mpz_sizeinbase(a.get_mp(), 2);
return msb(abs(a.get_mp()))+1;
}
/// floorLg -- floor of log_2(a)
@ -590,4 +755,6 @@ inline long ceilLg(int a) { // need this for Polynomial<int>
} //namespace CORE
#endif
#endif // _CORE_BIGINT_H_

View File

@ -27,6 +27,26 @@
#include <CGAL/CORE/BigInt.h>
#if 1
namespace CORE {
#ifdef CGAL_CORE_USE_GMP_BACKEND
typedef boost::multiprecision::mpq_rational BigRat;
#else
typedef boost::multiprecision::cpp_rational BigRat;
#endif
/// BigIntValue
BigInt BigIntValue(const BigRat& br) {
BigInt r, rem;
divide_qr(numerator(br), denominator(br), r, rem);
return r;
}
} // namespace CORE
#else
namespace CORE {
#ifdef CGAL_CORE_USE_GMP_BACKEND
@ -203,6 +223,8 @@ public:
get_mp() /= rhs.get_mp();
return *this;
}
/*
BigRat& operator <<=(unsigned long ul) {
makeCopy();
assert(false);
@ -215,6 +237,7 @@ public:
// AF no >> for Q get_mp() >>= ul;
return *this;
}
*/
//@}
/// \name div2, unary, increment, decrement operators
@ -259,11 +282,15 @@ public:
/// \name Helper Functions
//@{
/// Canonicalize
/*
void canonicalize() {
makeCopy();
assert(false);
// AF todo mpq_canonicalize(get_mp());
}
*/
/// Has Exact Division
static bool hasExactDivision() {
return true;
@ -398,6 +425,8 @@ inline bool isDivisible(const BigRat& x, const BigRat& y) {
r.get_mp() = x.get_mp() / y.get_mp();
return isInteger(r);
}
/*
inline BigRat operator<<(const BigRat& a, unsigned long ul) {
BigRat r;
assert(false);
@ -410,7 +439,7 @@ inline BigRat operator>>(const BigRat& a, unsigned long ul) {
// AF todo no >> for Q r.get_mp() = a.get_mp() >> ul;
return r;
}
*/
inline int cmp(const BigRat& x, const BigRat& y) {
return x.get_mp().compare(y.get_mp());
}
@ -477,4 +506,7 @@ inline BigInt BigIntValue(const BigRat& a) {
} //namespace CORE
#endif
#endif // _CORE_BIGRAT_H_

View File

@ -164,6 +164,7 @@ void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
// read base and compute digits
if (c == '0') {
assert(false); // no longer supported
in.get(c);
if (c == 'b') {
base = 2;
@ -202,7 +203,7 @@ void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
append_char(buffer, size, pos, '\0');
// convert string to bigint.
if (m.set_str(buffer, base) < 0)
if (set_str(m, buffer) < 0)
core_io_error_handler("CoreIO::read_from_file()","bad big number format.");
delete[] buffer;

View File

@ -30,6 +30,8 @@
#define __PROMOTE_H__
#include <CGAL/CORE/Impl.h>
#include <CGAL/CORE/BigInt.h>
#include <CGAL/CORE/BigRat.h>
namespace CORE {
@ -119,9 +121,9 @@ class Promotion<T, T> {
*
*/
class BigInt;
//class BigInt;
class BigFloat;
class BigRat;
//class BigRat;
class Expr;
DEFINE_MAX_TYPE(long, BigInt, BigInt)

View File

@ -277,7 +277,7 @@ const long halfLongMin = LONG_MIN /2;
struct _real_add {
template <class T>
static Real eval(const T& a, const T& b) {
return a+b;
return T(a+b);
}
// specialized for two long values
static Real eval(long a, long b) {
@ -291,7 +291,7 @@ struct _real_add {
struct _real_sub {
template <class T>
static Real eval(const T& a, const T& b) {
return a-b;
return T(a-b);
}
// specialized for two long values
static Real eval(long a, long b) {
@ -305,7 +305,7 @@ struct _real_sub {
struct _real_mul {
template <class T>
static Real eval(const T& a, const T& b) {
return a*b;
return T(a*b);
}
// specialized for two long values
static Real eval(long a, long b) {
@ -478,7 +478,7 @@ inline Real sqrt(const Real& x) {
// unary minus operator
template <class T>
inline Real Realbase_for<T>::operator-() const {
return -ker;
return -T(ker);
}
template <>
inline Real RealLong::operator-() const {

View File

@ -92,10 +92,10 @@ public:
int ID() const;
long longValue() const {
return ker.longValue();
return CORE::longValue(ker);
}
double doubleValue() const {
return ker.doubleValue();
return CORE::doubleValue(ker);
}
BigInt BigIntValue() const {
return BigInt(ker);
@ -231,7 +231,7 @@ inline BigInt RealBigInt::BigIntValue() const {
}
template<>
inline BigInt RealBigRat::BigIntValue() const {
return ker.BigIntValue();
return CORE::BigIntValue(ker);
}
template<>
inline BigInt RealBigFloat::BigIntValue() const {
@ -500,11 +500,11 @@ inline unsigned long RealBigRat::height() const {
// toString()
template<>
inline std::string RealBigInt::toString(long, bool) const {
return ker.get_str();
return ker.convert_to<std::string>();
}
template<>
inline std::string RealBigRat::toString(long, bool) const {
return ker.get_str();
return ker.convert_to<std::string>();
}
template<>
inline std::string RealBigFloat::toString(long prec, bool sci) const {

View File

@ -181,10 +181,12 @@ public:
if(::CORE::bitLength(err.m()+err.err()) >= digits_long){
long shift = ::CORE::bitLength(err.m()) - digits_long + 1 ;
//std::cout << "shift " << shift<< std::endl;
long new_err = ((err.m()+err.err()) >> shift).longValue()+1;
CORE::BigInt bi = (err.m() + err.err());
bi = bi >> shift;
long new_err = CORE::longValue(bi)+1;
err = CORE::BigFloat(0,new_err,0) * CORE::BigFloat::exp2(err.exp()*CORE::CHUNK_BIT+shift);
}else{
err = CORE::BigFloat(0,err.m().longValue()+err.err(),err.exp());
err = CORE::BigFloat(0, CORE::longValue(err.m())+err.err(),err.exp());
}
//print_bf(err,"new_err");

View File

@ -10,7 +10,6 @@
//
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
#ifndef CGAL_CORE_BIGINT_H
#define CGAL_CORE_BIGINT_H
@ -24,6 +23,8 @@
#include <CGAL/Residue.h>
#include <CGAL/Modular_traits.h>
#if 0
namespace CGAL {
//
@ -215,6 +216,7 @@ namespace Eigen {
};
};
}
#endif
#include <CGAL/enable_warnings.h>

View File

@ -10,7 +10,6 @@
//
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
#ifndef CGAL_CORE_BIGRAT_H
#define CGAL_CORE_BIGRAT_H
@ -21,6 +20,8 @@
#include <CGAL/CORE_coercion_traits.h>
#include <CGAL/CORE_Expr.h> // used for To_interval-functor
#if 0
//#if defined(CGAL_CORE_BIGRAT_NUMER_DENOM_ARE_MEMBERS)
// #define CGAL_CORE_NUMERATOR(X) ((X).numerator())
// #define CGAL_CORE_DENOMINATOR(X) ((X).denominator())
@ -252,6 +253,8 @@ namespace Eigen {
};
}
#endif
#include <CGAL/enable_warnings.h>
#endif // CGAL_CORE_BIGRAT_H

View File

@ -24,13 +24,12 @@
#include <CGAL/CORE/CORE.h>
//#include <NiX/Coercion_traits.h>
namespace CGAL {
//CORE internal coercions:
#if 0
// The following definitions reflect the interaction of the CORE number types
// with the built in types,
// CORE BigInt:
@ -46,7 +45,7 @@ namespace CGAL {
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float ,::CORE::BigRat)
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(double ,::CORE::BigRat)
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(::CORE::BigInt,::CORE::BigRat)
#endif
// CORE Expr:
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short ,::CORE::Expr)
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int ,::CORE::Expr)
@ -78,8 +77,8 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigInt>{
CORE::BigFloat result;
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 );
// AF CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
// AF CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
return result;
}
};
@ -98,8 +97,8 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigRat>{
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 );
// AF CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
// AF CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
return result;
}
};
@ -117,8 +116,8 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::Expr>{
Type operator()(const ::CORE::Expr x) const {
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 );
// AF CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()-result.err(),0,result.exp())) <= x );
// AF CGAL_postcondition( ::CORE::BigRat(::CORE::BigFloat(result.m()+result.err(),0,result.exp())) >= x );
return result;
}
};
@ -150,6 +149,8 @@ template <> struct Coercion_traits< ::CORE::Expr, CORE::BigFloat >
} //namespace CGAL
#endif // CGAL_USE_CORE
#endif //CGAL_CORE_COERCION_TRAITS_H 1
//EOF

View File

@ -57,6 +57,24 @@
// TODO: work on the coercions (end of the file)
namespace CGAL {
template<>
struct Needs_parens_as_product<typename boost::multiprecision::cpp_int>{
bool operator()(const typename boost::multiprecision::cpp_int& x){
return x < 0;
}
};
template<>
struct Needs_parens_as_product<typename boost::multiprecision::cpp_rational>{
bool operator()(const typename boost::multiprecision::cpp_rational& x){
if (denominator(x) != 1 )
return true;
else
return needs_parens_as_product(numerator(x)) ;
}
};
// Algebraic_structure_traits

View File

@ -33,6 +33,7 @@ void test_io(){
std::stringstream ss;
CGAL::IO::set_pretty_mode(ss);
ss << CGAL::IO::oformat(NT(1), CGAL::Parens_as_product_tag());
std::cout << ss.str() << std::endl;
assert( ss.str() == "1");
}{
std::stringstream ss;

View File

@ -19,18 +19,18 @@ void test_io(){
std::stringstream ss;
CGAL::IO::set_ascii_mode(ss);
ss << CGAL::IO::oformat(NT(1));
//std::cout << ss.str()<<std::endl;
assert( ss.str() == "1/1");
std::cout << ss.str()<<std::endl;
assert( ss.str() == "1");
}{
std::stringstream ss;
CGAL::IO::set_ascii_mode(ss);
ss << CGAL::IO::oformat(NT(0));
assert( ss.str() == "0/1");
assert( ss.str() == "0");
}{
std::stringstream ss;
CGAL::IO::set_ascii_mode(ss);
ss << CGAL::IO::oformat(NT(-1));
assert( ss.str() == "-1/1");
assert( ss.str() == "-1");
}
//MODE PRETTY
{