mirror of https://github.com/CGAL/cgal
Merge pull request #6035 from afabri/CORE-boost_mp_number-GF
CORE: Use boost::multiprecision::number API
This commit is contained in:
commit
54c5d19121
|
|
@ -2,6 +2,7 @@ Advancing_front_surface_reconstruction
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Distance_2
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ struct Rational_traits_base<Rational, true>
|
|||
{
|
||||
private:
|
||||
typedef Fraction_traits<Rational> FT;
|
||||
typedef typename FT::Decompose Decomose;
|
||||
typedef typename FT::Decompose Decompose;
|
||||
typedef typename FT::Compose Compose;
|
||||
|
||||
public:
|
||||
|
|
@ -61,13 +61,13 @@ public:
|
|||
|
||||
RT numerator (const Rational& r) const {
|
||||
RT num,den;
|
||||
Decomose()(r,num,den);
|
||||
Decompose()(r,num,den);
|
||||
return num;
|
||||
}
|
||||
|
||||
RT denominator (const Rational& r) const {
|
||||
RT num,den;
|
||||
Decomose()(r,num,den);
|
||||
Decompose()(r,num,den);
|
||||
return den;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ public:
|
|||
Integer alpha_num = Integer(1), int log_denom = 1
|
||||
) : alpha_num_(alpha_num),
|
||||
beta_num_((Integer(1) << log_denom) - alpha_num),
|
||||
half_((log_denom > 0) ? (Integer(1) << log_denom-1) : 0),
|
||||
half_((log_denom > 0) ? Integer(Integer(1) << log_denom-1) : 0),
|
||||
log_denom_(log_denom)
|
||||
{
|
||||
CGAL_precondition(log_denom_ >= 0);
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ polynomial_power_to_bernstein_approx(
|
|||
std::vector<Integer> f(n+1);
|
||||
polynomial_affine_transform_approx_log_denom(
|
||||
first, beyond, f.begin(),
|
||||
upper_num - lower_num, lower_num, log_denom,
|
||||
Integer(upper_num - lower_num), lower_num, log_denom,
|
||||
p+q,
|
||||
approx, log, logl
|
||||
);
|
||||
|
|
|
|||
|
|
@ -27,31 +27,10 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#if CGAL_USE_CORE
|
||||
namespace CORE { class BigInt; }
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace internal {
|
||||
|
||||
#if CGAL_USE_CORE
|
||||
// bugfix for CORE by Michael Kerber
|
||||
// why is there a specialized function for CORE?
|
||||
inline CORE::BigInt shift_integer_by(CORE::BigInt x, long shift){
|
||||
if( shift > 0 ){
|
||||
while(shift>63) {
|
||||
x = (x >> 63);
|
||||
shift-=63;
|
||||
}
|
||||
x = (x >> shift);
|
||||
}else{
|
||||
// add 0 bits
|
||||
x = (x << -shift);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Shiftable>
|
||||
Shiftable shift_integer_by(Shiftable x, long shift){
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ public:
|
|||
long operator()( CORE::BigFloat x ) const {
|
||||
CGAL_precondition(!CGAL::zero_in(x));
|
||||
x = CGAL::abs(x);
|
||||
return CORE::floorLg(x.m()-x.err())+x.exp()*CORE::CHUNK_BIT;
|
||||
return CORE::floorLg(CORE::BigInt(x.m()-x.err()))+x.exp()*CORE::CHUNK_BIT;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -337,7 +337,7 @@ public:
|
|||
// (already commented out in EXACUS)...
|
||||
// NiX_precond(!(NiX::in_zero(x) && NiX::singleton(x)));
|
||||
x = CGAL::abs(x);
|
||||
return CORE::ceilLg(x.m()+x.err())+x.exp()*CORE::CHUNK_BIT;
|
||||
return CORE::ceilLg(CORE::BigInt(x.m()+x.err()))+x.exp()*CORE::CHUNK_BIT;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ simple_bound_between(const Algebraic_real& a,
|
|||
final_mantissa = final_mantissa << 1;
|
||||
final_mantissa++;
|
||||
y_log--;
|
||||
x_m = x_m==0 ? 0 : x_m & ((Integer(1) << x_log) - 1); //x_m - CGAL::ipower(Integer(2),x_log);
|
||||
x_m = x_m==0 ? 0 : Integer(x_m & ((Integer(1) << x_log) - 1)); //x_m - CGAL::ipower(Integer(2),x_log);
|
||||
x_log = x_m==0 ? -1 : CGAL::internal::floor_log2_abs(x_m);
|
||||
}
|
||||
final_mantissa = final_mantissa << 1;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Algebraic_kernel_for_circles
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Filtered_kernel
|
||||
Installation
|
||||
Interval_support
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Algebraic_kernel_for_spheres
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Filtered_kernel
|
||||
Installation
|
||||
Interval_support
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Alpha_shapes_2
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Hash_map
|
||||
Homogeneous_kernel
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Alpha_shapes_3
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Filtered_kernel
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Alpha_wrap_3
|
|||
Arithmetic_kernel
|
||||
BGL
|
||||
Box_intersection_d
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Distance_2
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#ifdef CGAL_USE_BOOST_MP
|
||||
|
||||
#ifdef CGAL_USE_CORE
|
||||
#include <CGAL/CORE_arithmetic_kernel.h>
|
||||
#endif
|
||||
|
||||
//Currently already included in boost_mp.h
|
||||
//#include <boost/multiprecision/cpp_int.hpp>
|
||||
//#ifdef CGAL_USE_GMP
|
||||
|
|
@ -26,20 +30,29 @@
|
|||
//#endif
|
||||
|
||||
// FIXME: the could be several kernels based on Boost.Multiprecision.
|
||||
|
||||
namespace CGAL {
|
||||
/** \ingroup CGAL_Arithmetic_kernel
|
||||
* \brief The Boost.Multiprecision set of exact number types
|
||||
*/
|
||||
|
||||
#if !defined(CGAL_USE_CORE) || defined(CGAL_CORE_USE_GMP_BACKEND)
|
||||
struct BOOST_cpp_arithmetic_kernel : internal::Arithmetic_kernel_base {
|
||||
typedef boost::multiprecision::cpp_int Integer;
|
||||
typedef boost::multiprecision::cpp_rational Rational;
|
||||
};
|
||||
#else
|
||||
typedef CORE_arithmetic_kernel BOOST_cpp_arithmetic_kernel;
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_USE_GMP
|
||||
#if !defined(CGAL_USE_CORE) || !defined(CGAL_CORE_USE_GMP_BACKEND)
|
||||
struct BOOST_gmp_arithmetic_kernel : internal::Arithmetic_kernel_base {
|
||||
typedef boost::multiprecision::mpz_int Integer;
|
||||
typedef boost::multiprecision::mpq_rational Rational;
|
||||
};
|
||||
#else
|
||||
typedef CORE_arithmetic_kernel BOOST_gmp_arithmetic_kernel;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
|
|
|
|||
|
|
@ -55,14 +55,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct Get_arithmetic_kernel<CORE::BigInt>{
|
||||
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
template <>
|
||||
struct Get_arithmetic_kernel<CORE::BigRat>{
|
||||
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
template <>
|
||||
struct Get_arithmetic_kernel<CORE::Expr>{
|
||||
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
||||
|
|
@ -74,6 +66,8 @@ struct Get_arithmetic_kernel<CORE::BigFloat>{
|
|||
|
||||
} //namespace CGAL
|
||||
|
||||
#include <CGAL/BOOST_MP_arithmetic_kernel.h>
|
||||
|
||||
#endif // CGAL_USE_CORE
|
||||
|
||||
#endif // CGAL_CORE_ARITHMETIC_KERNEL_H
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ operator()(const Point_2& p, const X_monotone_curve_2& curve) const {
|
|||
auto points = painterOstream.getPointsList(curve);
|
||||
|
||||
QPoint p_viewport =
|
||||
view->mapFromScene(QPointF{p.x().doubleValue(), p.y().doubleValue()});
|
||||
view->mapFromScene(QPointF{CGAL::to_double(p.x()), CGAL::to_double(p.y())});
|
||||
|
||||
double min_dist = (std::numeric_limits<double>::max)();
|
||||
for (auto& vec : points) {
|
||||
|
|
|
|||
|
|
@ -3316,9 +3316,9 @@ public:
|
|||
// sqrt((r - s)^2 + t^2)
|
||||
//
|
||||
const int or_fact = (cv.orientation() == CLOCKWISE) ? -1 : 1;
|
||||
const Algebraic r = m_nt_traits->convert(or_fact * cv.r());
|
||||
const Algebraic s = m_nt_traits->convert(or_fact * cv.s());
|
||||
const Algebraic t = m_nt_traits->convert(or_fact * cv.t());
|
||||
const Algebraic r = m_nt_traits->convert(Integer(or_fact * cv.r()));
|
||||
const Algebraic s = m_nt_traits->convert(Integer(or_fact * cv.s()));
|
||||
const Algebraic t = m_nt_traits->convert(Integer(or_fact * cv.t()));
|
||||
const Algebraic cos_2phi = (r - s) / m_nt_traits->sqrt((r-s)*(r-s) + t*t);
|
||||
const Algebraic zero = 0;
|
||||
const Algebraic one = 1;
|
||||
|
|
@ -3363,8 +3363,8 @@ public:
|
|||
// 4*r*s - t^2 4*r*s - t^2
|
||||
//
|
||||
// The denominator (4*r*s - t^2) must be negative for hyperbolas.
|
||||
const Algebraic u = m_nt_traits->convert(or_fact * cv.u());
|
||||
const Algebraic v = m_nt_traits->convert(or_fact * cv.v());
|
||||
const Algebraic u = m_nt_traits->convert(Integer(or_fact * cv.u()));
|
||||
const Algebraic v = m_nt_traits->convert(Integer(or_fact * cv.v()));
|
||||
const Algebraic det = 4*r*s - t*t;
|
||||
Algebraic x0, y0;
|
||||
|
||||
|
|
@ -3803,9 +3803,9 @@ public:
|
|||
auto u = cv.u();
|
||||
auto v = cv.v();
|
||||
auto w = cv.w();
|
||||
Algebraic* xs_end = m_nt_traits->solve_quadratic_equation(t*t - four*r*s,
|
||||
two*t*v - four*s*u,
|
||||
v*v - four*s*w,
|
||||
Algebraic* xs_end = m_nt_traits->solve_quadratic_equation(Integer(t*t - four*r*s),
|
||||
Integer(two*t*v - four*s*u),
|
||||
Integer(v*v - four*s*w),
|
||||
xs);
|
||||
auto n_xs = static_cast<int>(xs_end - xs);
|
||||
|
||||
|
|
@ -3816,15 +3816,15 @@ public:
|
|||
|
||||
if (CGAL::sign(cv.t()) == ZERO) {
|
||||
// The two vertical tangency points have the same y coordinate:
|
||||
ys[0] = m_nt_traits->convert(-v) / m_nt_traits->convert(two*s);
|
||||
ys[0] = m_nt_traits->convert(Integer(- v)) / m_nt_traits->convert(Integer(two * s));
|
||||
n_ys = 1;
|
||||
}
|
||||
else {
|
||||
ys_end = m_nt_traits->solve_quadratic_equation(four*r*s*s - s*t*t,
|
||||
four*r*s*v - two*s*t*u,
|
||||
r*v*v - t*u*v +
|
||||
t*t*w,
|
||||
ys_end = m_nt_traits->solve_quadratic_equation(Integer(four*r*s*s - s*t*t),
|
||||
Integer(four*r*s*v - two*s*t*u),
|
||||
Integer((r*v*v - t*u*v) + (t*t*w)),
|
||||
ys);
|
||||
|
||||
n_ys = static_cast<int>(ys_end - ys);
|
||||
}
|
||||
|
||||
|
|
@ -3837,7 +3837,7 @@ public:
|
|||
}
|
||||
else {
|
||||
for (int j = 0; j < n_ys; ++j) {
|
||||
if (CGAL::compare(m_nt_traits->convert(two*s) * ys[j],
|
||||
if (CGAL::compare(m_nt_traits->convert(Integer(two*s)) * ys[j],
|
||||
-(m_nt_traits->convert(t) * xs[i] +
|
||||
m_nt_traits->convert(v))) == EQUAL)
|
||||
{
|
||||
|
|
@ -3904,10 +3904,11 @@ public:
|
|||
auto u = cv.u();
|
||||
auto v = cv.v();
|
||||
auto w = cv.w();
|
||||
Algebraic* ys_end = m_nt_traits->solve_quadratic_equation(t*t - four*r*s,
|
||||
two*t*u - four*r*v,
|
||||
u*u - four*r*w,
|
||||
ys);
|
||||
Algebraic* ys_end = m_nt_traits->template
|
||||
solve_quadratic_equation<Integer>(t*t - four*r*s,
|
||||
two*t*u - four*r*v,
|
||||
u*u - four*r*w,
|
||||
ys);
|
||||
auto n = static_cast<int>(ys_end - ys);
|
||||
|
||||
// Compute the x coordinates and construct the horizontal tangency points.
|
||||
|
|
@ -3915,7 +3916,7 @@ public:
|
|||
// Having computed y, x is the single solution to the quadratic equation
|
||||
// above, and since its discriminant is 0, x is simply given by:
|
||||
Algebraic x = -(m_nt_traits->convert(t)*ys[i] + m_nt_traits->convert(u)) /
|
||||
m_nt_traits->convert(two*r);
|
||||
m_nt_traits->convert(Integer(two*r));
|
||||
ps[i] = Point_2(x, ys[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1430,8 +1430,8 @@ protected:
|
|||
{
|
||||
// Actually compare the slopes.
|
||||
const bool swap_res = (sign_denom1 != sign_denom2);
|
||||
const CoordNT A = (cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0());
|
||||
const CoordNT B = (cv.x0() - x0())*p.y();
|
||||
const CoordNT A = NT(cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0());
|
||||
const CoordNT B = NT(cv.x0() - x0())*p.y();
|
||||
|
||||
slope_res = CGAL::compare (A, B);
|
||||
|
||||
|
|
|
|||
|
|
@ -1110,9 +1110,9 @@ protected:
|
|||
//
|
||||
Nt_traits nt_traits;
|
||||
const int or_fact = (m_orient == CLOCKWISE) ? -1 : 1;
|
||||
const Algebraic r = nt_traits.convert(or_fact * m_r);
|
||||
const Algebraic s = nt_traits.convert(or_fact * m_s);
|
||||
const Algebraic t = nt_traits.convert(or_fact * m_t);
|
||||
const Algebraic r = nt_traits.convert(Integer(or_fact * m_r));
|
||||
const Algebraic s = nt_traits.convert(Integer(or_fact * m_s));
|
||||
const Algebraic t = nt_traits.convert(Integer(or_fact * m_t));
|
||||
const Algebraic cos_2phi = (r - s) / nt_traits.sqrt((r-s)*(r-s) + t*t);
|
||||
const Algebraic zero = 0;
|
||||
const Algebraic one = 1;
|
||||
|
|
@ -1158,8 +1158,8 @@ protected:
|
|||
// 4*r*s - t^2 4*r*s - t^2
|
||||
//
|
||||
// The denominator (4*r*s - t^2) must be negative for hyperbolas.
|
||||
const Algebraic u = nt_traits.convert(or_fact * m_u);
|
||||
const Algebraic v = nt_traits.convert(or_fact * m_v);
|
||||
const Algebraic u = nt_traits.convert(Integer(or_fact * m_u));
|
||||
const Algebraic v = nt_traits.convert(Integer(or_fact * m_v));
|
||||
const Algebraic det = 4*r*s - t*t;
|
||||
Algebraic x0, y0;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ int compute_resultant_roots(const Nt_traits& nt_traits,
|
|||
}
|
||||
|
||||
// Act according to the degree of the first conic curve.
|
||||
const typename Nt_traits::Integer two = 2;
|
||||
typename Nt_traits::Integer c[5];
|
||||
typedef typename Nt_traits::Integer Integer;
|
||||
const Integer two = 2;
|
||||
Integer c[5];
|
||||
unsigned int degree = 4;
|
||||
typename Nt_traits::Algebraic* xs_end;
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ int compute_resultant_roots(const Nt_traits& nt_traits,
|
|||
// The first curve has no quadratic coefficients, and represents a line.
|
||||
if (CGAL::sign (v1) == ZERO) {
|
||||
// The first line is u1*x + w1 = 0, therefore:
|
||||
xs[0] = nt_traits.convert(-w1) / nt_traits.convert(u1);
|
||||
xs[0] = nt_traits.convert(Integer(- w1)) / nt_traits.convert(u1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +88,7 @@ int compute_resultant_roots(const Nt_traits& nt_traits,
|
|||
// Return if the two lines are parallel
|
||||
if (CGAL::sign (c[1]) == ZERO) return 0;
|
||||
|
||||
xs[0] = nt_traits.convert(-c[0]) / nt_traits.convert(c[1]);
|
||||
xs[0] = nt_traits.convert(Integer(- c[0])) / nt_traits.convert(c[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,10 +225,11 @@ public:
|
|||
if (CGAL::compare(
|
||||
CGAL::width(y_bfi),
|
||||
CGAL::lower(CGAL::abs(y_bfi)) * eps)
|
||||
== SMALLER)
|
||||
== SMALLER){
|
||||
return std::make_pair(
|
||||
Bound(CGAL::lower(y_bfi)),
|
||||
Bound(CGAL::upper(y_bfi)));
|
||||
}
|
||||
}
|
||||
else precision*=2;
|
||||
}
|
||||
|
|
@ -287,10 +288,11 @@ private:
|
|||
if (CGAL::zero_in(y_denom_bfi) == false)
|
||||
{
|
||||
BFI y_bfi(y_numer_bfi/y_denom_bfi);
|
||||
if (CGAL::width(y_bfi) < eps )
|
||||
if (CGAL::width(y_bfi) < eps ){
|
||||
return std::make_pair(
|
||||
Bound(CGAL::lower(y_bfi)),
|
||||
Bound(CGAL::upper(y_bfi)));
|
||||
}
|
||||
|
||||
}
|
||||
else precision*=2;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ public:
|
|||
ix1 = scaled_x1.BigIntValue();
|
||||
ix2 = scaled_x2.BigIntValue();
|
||||
|
||||
if (CORE::abs (ix2 - ix1) > one)
|
||||
if (CGAL::abs (ix2 - ix1) > one)
|
||||
break;
|
||||
|
||||
// Scale the values by a factor of 2.
|
||||
|
|
@ -179,9 +179,9 @@ public:
|
|||
temp_gcd = numer_gcd;
|
||||
|
||||
denom_lcm *= denom;
|
||||
denom_lcm /= CORE::gcd (temp_lcm, denom);
|
||||
denom_lcm /= CGAL::gcd (temp_lcm, denom);
|
||||
|
||||
numer_gcd = CORE::gcd (temp_gcd, numer);
|
||||
numer_gcd = CGAL::gcd (temp_gcd, numer);
|
||||
}
|
||||
|
||||
++q_iter;
|
||||
|
|
@ -246,8 +246,8 @@ public:
|
|||
|
||||
if (sign_disc == ZERO)
|
||||
{
|
||||
// We have one real root with mutliplicity 2.
|
||||
*oi = -Algebraic (b) / Algebraic (2*a);
|
||||
// We have one real root with multiplicity 2.
|
||||
*oi = -Algebraic (b) / Algebraic (NT(2*a));
|
||||
++oi;
|
||||
}
|
||||
else if (sign_disc == POSITIVE)
|
||||
|
|
@ -255,7 +255,7 @@ public:
|
|||
// We have two distinct real roots. We return them in ascending order.
|
||||
const Algebraic sqrt_disc = CGAL::sqrt (Algebraic (disc));
|
||||
const Algebraic alg_b = b;
|
||||
const Algebraic alg_2a = 2*a;
|
||||
const Algebraic alg_2a = NT(2*a);
|
||||
|
||||
if (sign_a == POSITIVE)
|
||||
{
|
||||
|
|
@ -334,7 +334,7 @@ public:
|
|||
temp_lcm = denom_lcm;
|
||||
|
||||
denom_lcm *= denom;
|
||||
denom_lcm /= CORE::gcd (temp_lcm, denom);
|
||||
denom_lcm /= CGAL::gcd (temp_lcm, denom);
|
||||
}
|
||||
|
||||
index--;
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ void draw(const Arc_2& arc,
|
|||
get_pixel_coords(l, y_clip, pix_beg);
|
||||
get_pixel_coords(ptmp->left, it->second ? engine.y_max_r :
|
||||
engine.y_min_r, pix_end);
|
||||
if(CGAL_ABS(ptmp->left - l) <= engine.pixel_w_r*2) {
|
||||
if(CGAL_ABS(Rational(ptmp->left - l)) <= engine.pixel_w_r*2) {
|
||||
|
||||
Coordinate_2 xy(Coordinate_1(pt), *support, arc.arcno());
|
||||
Rational _;
|
||||
|
|
|
|||
|
|
@ -695,7 +695,7 @@ bool get_range_QF_1(int var, const NT& l_, const NT& r_, const NT& key,
|
|||
while(der_it != der_begin) {
|
||||
--der_it;
|
||||
|
||||
e1 = xsum_abs * e1 + CGAL_ABS(x1 * z1);
|
||||
e1 = xsum_abs * e1 + CGAL_ABS(NT(x1 * z1));
|
||||
z1 = x0*z1 + x1*y1;
|
||||
y1 = y1*x0 + x1*y0;
|
||||
y0 = x0*y0 + extract(*cache_it)*(*der_it);
|
||||
|
|
@ -726,7 +726,7 @@ bool get_range_QF_1(int var, const NT& l_, const NT& r_, const NT& key,
|
|||
NT y0 = extract(*cache_it), y1(0), z1(0), e1(0);
|
||||
while(cache_it != begin) {
|
||||
--cache_it;
|
||||
e1 = xsum_abs * e1 + CGAL_ABS(x1*z1);
|
||||
e1 = xsum_abs * e1 + CGAL_ABS(NT(x1*z1));
|
||||
z1 = x0*z1 + x1*y1;
|
||||
y1 = y1*x0 + x1*y0;
|
||||
y0 = x0*y0 + extract(*cache_it);
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ struct Curve_renderer_traits<CGAL::Interval_nt<true>, CORE::BigRat > :
|
|||
|
||||
//! Specialization for \c CORE::BigFloat
|
||||
template <>
|
||||
struct Curve_renderer_traits<CORE::BigFloat, class CORE::BigRat>
|
||||
struct Curve_renderer_traits<CORE::BigFloat, CORE::BigRat>
|
||||
: public Curve_renderer_traits_base<CORE::BigFloat, CORE::BigInt,
|
||||
CORE::BigRat> {
|
||||
|
||||
|
|
@ -347,7 +347,7 @@ struct Curve_renderer_traits<CORE::BigFloat, class CORE::BigRat>
|
|||
typedef Integer result_type;
|
||||
|
||||
Integer operator()(const Rational& x) const {
|
||||
return x.BigIntValue();
|
||||
return numerator(x)/denominator(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -400,7 +400,7 @@ struct Curve_renderer_traits<CORE::BigRat, CORE::BigRat> :
|
|||
typedef Integer result_type;
|
||||
|
||||
Integer operator()(const Rational& x) const {
|
||||
return x.BigIntValue();
|
||||
return numerator(x)/denominator(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -409,9 +409,7 @@ struct Curve_renderer_traits<CORE::BigRat, CORE::BigRat> :
|
|||
typedef std::size_t result_type;
|
||||
|
||||
inline result_type operator()(const Float& key) const {
|
||||
const CORE::BigRatRep& rep = key.getRep();
|
||||
std::size_t ret = reinterpret_cast<std::size_t>(&rep);
|
||||
return ret;
|
||||
return std::hash<Float>()(key);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -877,7 +877,7 @@ endfunction()
|
|||
#---------------------------------------------------------------------#
|
||||
function(test_polycurve_conic_traits)
|
||||
# echo polycurve test starting
|
||||
if(CGAL_DISABLE_GMP)
|
||||
if(NOT CGAL_Core_FOUND)
|
||||
MESSAGE(STATUS "test_polycurve_conic_traits requires CORE and will not be executed")
|
||||
return()
|
||||
endif()
|
||||
|
|
@ -948,7 +948,7 @@ endfunction()
|
|||
# polycurve bezier traits
|
||||
#---------------------------------------------------------------------#
|
||||
function(test_polycurve_bezier_traits)
|
||||
if(CGAL_DISABLE_GMP)
|
||||
if(NOT CGAL_Core_FOUND)
|
||||
MESSAGE(STATUS "test_polycurve_bezier_traits requires CORE and will not be executed")
|
||||
return()
|
||||
endif()
|
||||
|
|
@ -1057,7 +1057,7 @@ endfunction()
|
|||
# conic traits
|
||||
#---------------------------------------------------------------------#
|
||||
function(test_conic_traits)
|
||||
if(CGAL_DISABLE_GMP)
|
||||
if(NOT CGAL_Core_FOUND)
|
||||
MESSAGE(STATUS "test_conic_traits requires CORE and will not be executed")
|
||||
return()
|
||||
endif()
|
||||
|
|
@ -1188,7 +1188,7 @@ endfunction()
|
|||
# bezier traits
|
||||
#---------------------------------------------------------------------#
|
||||
function(test_bezier_traits)
|
||||
if(CGAL_DISABLE_GMP)
|
||||
if(NOT CGAL_Core_FOUND)
|
||||
MESSAGE(STATUS "test_bezier_traits requires CORE and will not be executed")
|
||||
return()
|
||||
endif()
|
||||
|
|
@ -1235,7 +1235,7 @@ endfunction()
|
|||
# rational arc traits
|
||||
#---------------------------------------------------------------------#
|
||||
function(test_rational_arc_traits)
|
||||
if(CGAL_DISABLE_GMP)
|
||||
if(NOT CGAL_Core_FOUND)
|
||||
MESSAGE(STATUS "test_rational_arc_traits requires CORE and will not be executed")
|
||||
return()
|
||||
endif()
|
||||
|
|
@ -1302,7 +1302,7 @@ endfunction()
|
|||
#---------------------------------------------------------------------#
|
||||
function(test_algebraic_traits_core)
|
||||
#TODO: Adapt
|
||||
if(CGAL_DISABLE_GMP)
|
||||
if(NOT CGAL_Core_FOUND)
|
||||
MESSAGE(STATUS "test_algebraic_traits_core requires CORE and will not be executed")
|
||||
return()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@
|
|||
# We need the bezier curve (not polycurve) to contruct a bezier point.
|
||||
#
|
||||
# Point ID: 0
|
||||
r c 4 0 0 500 200 100 200 900 0 0.5
|
||||
r c 4 0 0 500 200 100 200 900 0 1/2
|
||||
# Point ID: 1
|
||||
r c 4 900 0 1200 600 1500 400 900 600 0.3
|
||||
r c 4 900 0 1200 600 1500 400 900 600 3/10
|
||||
# Point id: 2
|
||||
r c 4 0 0 100 200 500 200 900 0 0.0
|
||||
r c 4 0 0 100 200 500 200 900 0 0
|
||||
# Point id: 3
|
||||
r c 4 900 0 1200 300 1500 400 2000 450 1.0
|
||||
r c 4 900 0 1200 300 1500 400 2000 450 1
|
||||
# Point id: 4
|
||||
r c 4 2000 450 2100 300 2200 200 2300 450 0.0
|
||||
r c 4 2000 450 2100 300 2200 200 2300 450 0
|
||||
# Point id: 5
|
||||
r c 4 2300 450 2500 500 2800 600 3000 450 1.0
|
||||
r c 4 2300 450 2500 500 2800 600 3000 450 1
|
||||
# Point id: 6
|
||||
r c 4 0 0 100 200 500 200 900 0 0.0
|
||||
r c 4 0 0 100 200 500 200 900 0 0
|
||||
# Point id: 7
|
||||
r c 4 2300 450 2500 500 2800 600 3000 450 1.0
|
||||
r c 4 2300 450 2500 500 2800 600 3000 450 1
|
||||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
Arithmetic_kernel
|
||||
BGL
|
||||
Barycentric_coordinates_2
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Distance_2
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
Arithmetic_kernel
|
||||
Arrangement_on_surface_2
|
||||
Boolean_set_operations_2
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circular_kernel_2
|
||||
Circulator
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -106,6 +106,9 @@ public:
|
|||
explicit BigFloat(BigFloatRep* r, bool) : RCBigFloat(r) {
|
||||
}
|
||||
|
||||
operator BigRat() const {
|
||||
return this->BigRatValue();
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
|
|
@ -510,32 +513,6 @@ inline long minStar(long m, long n) {
|
|||
}
|
||||
/// \name Functions for Compatibility with BigInt (needed by Poly, Curves)
|
||||
//@{
|
||||
/// isDivisible(a,b) = "is a divisible by b"
|
||||
/** Assuming that a and b are in coanonized forms.
|
||||
Defined to be true if mantissa(b) | mantissa(a) &&
|
||||
exp(b) = min*(exp(b), exp(a)).
|
||||
* This concepts assume a and b are exact BigFloats.
|
||||
*/
|
||||
inline bool isDivisible(const BigFloat& a, const BigFloat& b) {
|
||||
// assert: a and b are exact BigFloats.
|
||||
if (sign(a.m()) == 0) return true;
|
||||
if (sign(b.m()) == 0) return false;
|
||||
unsigned long bin_a = getBinExpo(a.m());
|
||||
unsigned long bin_b = getBinExpo(b.m());
|
||||
|
||||
BigInt m_a = a.m() >> bin_a;
|
||||
BigInt m_b = b.m() >> bin_b;
|
||||
long e_a = bin_a + BigFloatRep::bits(a.exp());
|
||||
long e_b = bin_b + BigFloatRep::bits(b.exp());
|
||||
long dx = minStar(e_a, e_b);
|
||||
|
||||
return isDivisible(m_a, m_b) && (dx == e_b);
|
||||
}
|
||||
|
||||
inline bool isDivisible(double x, double y) {
|
||||
//Are these exact?
|
||||
return isDivisible(BigFloat(x), BigFloat(y));
|
||||
}
|
||||
|
||||
/// div_exact(x,y) returns the BigFloat quotient of x divided by y
|
||||
/** This is defined only if isDivisible(x,y).
|
||||
|
|
@ -548,7 +525,6 @@ inline bool isDivisible(double x, double y) {
|
|||
// normalizing it then we get zero.
|
||||
inline BigFloat div_exact(const BigFloat& x, const BigFloat& y) {
|
||||
BigInt z;
|
||||
CGAL_assertion (isDivisible(x,y));
|
||||
unsigned long bin_x = getBinExpo(x.m());
|
||||
unsigned long bin_y = getBinExpo(y.m());
|
||||
|
||||
|
|
@ -615,15 +591,20 @@ inline BigFloat gcd(const BigFloat& a, const BigFloat& b) {
|
|||
//}//
|
||||
|
||||
|
||||
// constructor BigRat from BigFloat
|
||||
inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){
|
||||
*this = f.BigRatValue();
|
||||
inline double doubleValue(const BigFloat& bf)
|
||||
{
|
||||
return bf.doubleValue();
|
||||
}
|
||||
|
||||
inline long longValue(const BigFloat& bf)
|
||||
{
|
||||
return bf.longValue();
|
||||
}
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#include <CGAL/CORE/BigFloat_impl.h>
|
||||
#include <CGAL/CORE/CoreIO_impl.h>
|
||||
#endif // CGAL_HEADER_ONLY
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ inline void BigFloatRep::eliminateTrailingZeroes() {
|
|||
// builtin functions
|
||||
inline extLong BigFloatRep::lMSB() const {
|
||||
if (!isZeroIn())
|
||||
return extLong(floorLg(abs(m) - err)) + bits(exp);
|
||||
return extLong(floorLg(BigInt(abs(m) - err))) + bits(exp);
|
||||
else
|
||||
return extLong(CORE_negInfty);
|
||||
}
|
||||
|
|
@ -327,7 +327,7 @@ inline extLong BigFloatRep::lMSB() const {
|
|||
* Not well-defined if zero is in the interval.
|
||||
*/
|
||||
inline extLong BigFloatRep::uMSB() const {
|
||||
return extLong(floorLg(abs(m) + err)) + bits(exp);
|
||||
return extLong(floorLg(BigInt(abs(m) + err))) + bits(exp);
|
||||
}
|
||||
|
||||
inline extLong BigFloatRep::MSB() const {
|
||||
|
|
|
|||
|
|
@ -194,8 +194,7 @@ void BigFloatRep :: truncM(const BigFloatRep& B, const extLong& r, const extLong
|
|||
err = 2;
|
||||
exp = B.exp + t;
|
||||
} else // t < chunkCeil(clLg(B.err))
|
||||
core_error(std::string("BigFloat error: truncM called with stricter")
|
||||
+ "precision than current error.", __FILE__, __LINE__, true);
|
||||
CGAL_error_msg("BigFloat error: truncM called with stricter precision than current error.");
|
||||
} else {// B.m == 0
|
||||
long t = chunkFloor(- a.asLong()) - B.exp;
|
||||
|
||||
|
|
@ -204,8 +203,7 @@ void BigFloatRep :: truncM(const BigFloatRep& B, const extLong& r, const extLong
|
|||
err = 1;
|
||||
exp = B.exp + t;
|
||||
} else // t < chunkCeil(clLg(B.err))
|
||||
core_error(std::string("BigFloat error: truncM called with stricter")
|
||||
+ "precision than current error.", __FILE__, __LINE__, true);
|
||||
CGAL_error_msg("BigFloat error: truncM called with stricter precision than current error.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +214,7 @@ CGAL_INLINE_FUNCTION
|
|||
void BigFloatRep::approx(const BigFloatRep& B,
|
||||
const extLong& r, const extLong& a) {
|
||||
if (B.err) {
|
||||
if (1 + clLg(B.err) <= bitLength(B.m))
|
||||
if (static_cast<std::size_t>(1 + clLg(B.err)) <= bitLength(B.m))
|
||||
truncM(B, r + 1, a);
|
||||
else // 1 + clLg(B.err) > lg(B.m)
|
||||
truncM(B, CORE_posInfty, a);
|
||||
|
|
@ -258,7 +256,7 @@ void BigFloatRep::div(const BigInt& N, const BigInt& D,
|
|||
exp = 0;
|
||||
}
|
||||
} else // D == 0
|
||||
core_error( "BigFloat error: zero divisor.", __FILE__, __LINE__, true);
|
||||
CGAL_error_msg( "BigFloat error: zero divisor.");
|
||||
|
||||
// Call normalization globally -- IP 10/9/98
|
||||
normal();
|
||||
|
|
@ -455,6 +453,7 @@ void BigFloatRep::centerize(const BigFloatRep& a, const BigFloatRep& b) {
|
|||
// Zilin & Vikram, 08/24/04
|
||||
// err = 1 + longValue(chunkShift(r.m, r.exp - exp));
|
||||
BigInt E = chunkShift(r.m, r.exp - exp);
|
||||
E = abs(E);
|
||||
bigNormal(E);
|
||||
}
|
||||
|
||||
|
|
@ -538,8 +537,7 @@ void BigFloatRep :: div(const BigFloatRep& x, const BigFloatRep& y,
|
|||
bigNormal(bigErr);
|
||||
}
|
||||
} else {// y.m <= y.err
|
||||
core_error("BigFloat error: possible zero divisor.",
|
||||
__FILE__, __LINE__, true);
|
||||
CGAL_error_msg("BigFloat error: possible zero divisor.");
|
||||
}
|
||||
|
||||
// Call normalization globally -- IP 10/9/98
|
||||
|
|
@ -734,8 +732,7 @@ void BigFloatRep::sqrt(const BigFloatRep& x, const extLong& a, const BigFloat& A
|
|||
} // end of case with error in mantissa
|
||||
}//else
|
||||
} else
|
||||
core_error("BigFloat error: squareroot called with negative operand.",
|
||||
__FILE__, __LINE__, true);
|
||||
CGAL_error_msg("BigFloat error: squareroot called with negative operand.");
|
||||
} //sqrt with initial approximation
|
||||
|
||||
// compareMExp(x)
|
||||
|
|
@ -822,8 +819,7 @@ BigFloatRep::toDecimal(unsigned int width, bool Scientific) const {
|
|||
if (err > 0 && err >= abs(m)) {
|
||||
// if err is larger than mantissa, sign and significant values
|
||||
// can not be determined.
|
||||
core_error("BigFloat error: Error is too big!",
|
||||
__FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(true, "BigFloat error: Error is too big!");
|
||||
decOut.rep = "0.0e0"; // error is too big
|
||||
decOut.isScientific = false;
|
||||
decOut.noSignificant = 0;
|
||||
|
|
@ -869,7 +865,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.
|
||||
|
|
@ -1003,8 +999,7 @@ void BigFloatRep :: fromString(const char *str, extLong prec ) {
|
|||
// NOTE: prec defaults to get_static_defBigFloatInputDigits() (see BigFloat.h)
|
||||
// check that prec is not INFTY
|
||||
if (prec.isInfty())
|
||||
core_error("BigFloat error: infinite precision not allowed",
|
||||
__FILE__, __LINE__, true);
|
||||
CGAL_error_msg("BigFloat error: infinite precision not allowed");
|
||||
|
||||
const char *e = strchr(str, 'e');
|
||||
int dot = 0;
|
||||
|
|
|
|||
|
|
@ -24,448 +24,113 @@
|
|||
#ifndef _CORE_BIGINT_H_
|
||||
#define _CORE_BIGINT_H_
|
||||
|
||||
#include <CGAL/CORE/Gmp.h>
|
||||
#include <CGAL/boost_mp_type.h>
|
||||
#include <CGAL/CORE/RefCount.h>
|
||||
#include <CGAL/CORE/MemoryPool.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
#if !(defined(CGAL_CORE_USE_BOOST_BACKEND) && BOOST_VERSION > 107900 && defined(CGAL_USE_BOOST_MP)) && !defined(CGAL_DISABLE_GMP)
|
||||
#define CGAL_CORE_USE_GMP_BACKEND 1
|
||||
#endif
|
||||
|
||||
namespace CORE {
|
||||
|
||||
#ifdef CGAL_CORE_USE_GMP_BACKEND
|
||||
typedef boost::multiprecision::mpz_int BigInt;
|
||||
#else
|
||||
typedef boost::multiprecision::cpp_int BigInt;
|
||||
#endif
|
||||
|
||||
class BigIntRep : public RCRepImpl<BigIntRep> {
|
||||
public:
|
||||
BigIntRep() {
|
||||
mpz_init(mp);
|
||||
}
|
||||
// Note : should the copy-ctor be allowed at all ? [Sylvain Pion]
|
||||
BigIntRep(const BigIntRep& z) : RCRepImpl<BigIntRep>() {
|
||||
mpz_init_set(mp, z.mp);
|
||||
}
|
||||
BigIntRep(signed char c) {
|
||||
mpz_init_set_si(mp, c);
|
||||
}
|
||||
BigIntRep(unsigned char c) {
|
||||
mpz_init_set_ui(mp, c);
|
||||
}
|
||||
BigIntRep(signed int i) {
|
||||
mpz_init_set_si(mp, i);
|
||||
}
|
||||
BigIntRep(unsigned int i) {
|
||||
mpz_init_set_ui(mp, i);
|
||||
}
|
||||
BigIntRep(signed short int s) {
|
||||
mpz_init_set_si(mp, s);
|
||||
}
|
||||
BigIntRep(unsigned short int s) {
|
||||
mpz_init_set_ui(mp, s);
|
||||
}
|
||||
BigIntRep(signed long int l) {
|
||||
mpz_init_set_si(mp, l);
|
||||
}
|
||||
BigIntRep(unsigned long int l) {
|
||||
mpz_init_set_ui(mp, l);
|
||||
}
|
||||
BigIntRep(float f) {
|
||||
mpz_init_set_d(mp, f);
|
||||
}
|
||||
BigIntRep(double d) {
|
||||
mpz_init_set_d(mp, d);
|
||||
}
|
||||
BigIntRep(const char* s, int base=0) {
|
||||
mpz_init_set_str(mp, s, base);
|
||||
}
|
||||
BigIntRep(const std::string& s, int base=0) {
|
||||
mpz_init_set_str(mp, s.c_str(), base);
|
||||
}
|
||||
explicit BigIntRep(mpz_srcptr z) {
|
||||
mpz_init_set(mp, z);
|
||||
}
|
||||
~BigIntRep() {
|
||||
mpz_clear(mp);
|
||||
}
|
||||
|
||||
CGAL_CORE_EXPORT CORE_NEW(BigIntRep)
|
||||
CGAL_CORE_EXPORT CORE_DELETE(BigIntRep)
|
||||
|
||||
mpz_srcptr get_mp() const {
|
||||
return mp;
|
||||
}
|
||||
mpz_ptr get_mp() {
|
||||
return mp;
|
||||
}
|
||||
private:
|
||||
mpz_t mp;
|
||||
};
|
||||
|
||||
typedef RCImpl<BigIntRep> RCBigInt;
|
||||
class CGAL_CORE_EXPORT BigInt : public RCBigInt {
|
||||
public:
|
||||
/// \name Constructors
|
||||
//@{
|
||||
/// default constructor
|
||||
BigInt() : RCBigInt(new BigIntRep()) {}
|
||||
/// constructor for <tt>signed char</tt>
|
||||
BigInt(signed char x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>unsigned char</tt>
|
||||
BigInt(unsigned char x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>signed short int</tt>
|
||||
BigInt(signed short int x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>unsigned short int</tt>
|
||||
BigInt(unsigned short int x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>signed int</tt>
|
||||
BigInt(signed int x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>unsigned int</tt>
|
||||
BigInt(unsigned int x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>signed long int</tt>
|
||||
BigInt(signed long int x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>unsigned long int</tt>
|
||||
BigInt(unsigned long int x) : RCBigInt(new BigIntRep(x)) {}
|
||||
/// constructor for <tt>float</tt>
|
||||
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>mpz_srcptr</tt>
|
||||
explicit BigInt(mpz_srcptr z) : RCBigInt(new BigIntRep(z)) {}
|
||||
//@}
|
||||
|
||||
/// \name Copy-Assignment-Destructor
|
||||
//@{
|
||||
/// copy constructor
|
||||
BigInt(const BigInt& rhs) : RCBigInt(rhs) {
|
||||
rep->incRef();
|
||||
}
|
||||
/// assignment operator
|
||||
BigInt& operator=(const BigInt& rhs) {
|
||||
if (this != &rhs) {
|
||||
rep->decRef();
|
||||
rep = rhs.rep;
|
||||
rep->incRef();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
/// destructor
|
||||
~BigInt() {
|
||||
rep->decRef();
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name Overloaded operators
|
||||
//@{
|
||||
BigInt& operator +=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_add(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator -=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_sub(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator *=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_mul(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator /=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_tdiv_q(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator %=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_tdiv_r(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator &=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_and(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator |=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_ior(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator ^=(const BigInt& rhs) {
|
||||
makeCopy();
|
||||
mpz_xor(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator <<=(unsigned long ul) {
|
||||
makeCopy();
|
||||
mpz_mul_2exp(get_mp(), get_mp(), ul);
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator >>=(unsigned long ul) {
|
||||
makeCopy();
|
||||
mpz_tdiv_q_2exp(get_mp(), get_mp(), ul);
|
||||
return *this;
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name unary, increment, decrement operators
|
||||
//@{
|
||||
BigInt operator+() const {
|
||||
return BigInt(*this);
|
||||
}
|
||||
BigInt operator-() const {
|
||||
BigInt r;
|
||||
mpz_neg(r.get_mp(), get_mp());
|
||||
return r;
|
||||
}
|
||||
BigInt& operator++() {
|
||||
makeCopy();
|
||||
mpz_add_ui(get_mp(), get_mp(), 1);
|
||||
return *this;
|
||||
}
|
||||
BigInt& operator--() {
|
||||
makeCopy();
|
||||
mpz_sub_ui(get_mp(), get_mp(), 1);
|
||||
return *this;
|
||||
}
|
||||
BigInt operator++(int) {
|
||||
BigInt r(*this);
|
||||
++(*this);
|
||||
return r;
|
||||
}
|
||||
BigInt operator--(int) {
|
||||
BigInt r(*this);
|
||||
--(*this);
|
||||
return r;
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name Helper Functions
|
||||
//@{
|
||||
/// Has Exact Division
|
||||
static bool hasExactDivision() {
|
||||
return false;
|
||||
}
|
||||
/// get mpz pointer (const)
|
||||
mpz_srcptr get_mp() const {
|
||||
return rep->get_mp();
|
||||
}
|
||||
/// get mpz pointer
|
||||
mpz_ptr get_mp() {
|
||||
return rep->get_mp();
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name String Conversion Functions
|
||||
//@{
|
||||
/// set value from <tt>const char*</tt>
|
||||
int set_str(const char* s, int base = 0) {
|
||||
makeCopy();
|
||||
return mpz_set_str(get_mp(), s, base);
|
||||
}
|
||||
/// convert to <tt>std::string</tt>
|
||||
std::string get_str(int base = 10) const {
|
||||
int n = mpz_sizeinbase (get_mp(), base) + 2;
|
||||
char *buffer = new char[n];
|
||||
mpz_get_str(buffer, base, get_mp());
|
||||
std::string result(buffer);
|
||||
delete [] buffer;
|
||||
return result;
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name Conversion Functions
|
||||
//@{
|
||||
/// intValue
|
||||
int intValue() const {
|
||||
return static_cast<int>(mpz_get_si(get_mp()));
|
||||
}
|
||||
/// longValue
|
||||
long longValue() const {
|
||||
return mpz_get_si(get_mp());
|
||||
}
|
||||
/// ulongValue
|
||||
unsigned long ulongValue() const {
|
||||
return mpz_get_ui(get_mp());
|
||||
}
|
||||
/// doubleValue
|
||||
double doubleValue() const {
|
||||
return mpz_get_d(get_mp());
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
inline BigInt operator+(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_add(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator-(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_sub(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator*(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_mul(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator/(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_tdiv_q(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator%(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_tdiv_r(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator&(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_and(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator|(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_ior(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator^(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_xor(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator<<(const BigInt& a, unsigned long ul) {
|
||||
BigInt r;
|
||||
mpz_mul_2exp(r.get_mp(), a.get_mp(), ul);
|
||||
return r;
|
||||
}
|
||||
inline BigInt operator>>(const BigInt& a, unsigned long ul) {
|
||||
BigInt r;
|
||||
mpz_tdiv_q_2exp(r.get_mp(), a.get_mp(), ul);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline int cmp(const BigInt& x, const BigInt& y) {
|
||||
return mpz_cmp(x.get_mp(), y.get_mp());
|
||||
}
|
||||
inline bool operator==(const BigInt& a, const BigInt& b) {
|
||||
return cmp(a, b) == 0;
|
||||
}
|
||||
inline bool operator!=(const BigInt& a, const BigInt& b) {
|
||||
return cmp(a, b) != 0;
|
||||
}
|
||||
inline bool operator>=(const BigInt& a, const BigInt& b) {
|
||||
return cmp(a, b) >= 0;
|
||||
}
|
||||
inline bool operator>(const BigInt& a, const BigInt& b) {
|
||||
return cmp(a, b) > 0;
|
||||
}
|
||||
inline bool operator<=(const BigInt& a, const BigInt& b) {
|
||||
return cmp(a, b) <= 0;
|
||||
}
|
||||
inline bool operator<(const BigInt& a, const BigInt& b) {
|
||||
return cmp(a, b) < 0;
|
||||
return x.compare(y);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& o, const BigInt& x) {
|
||||
//return CORE::operator<<(o, x.get_mp());
|
||||
return CORE::io_write(o, x.get_mp());
|
||||
}
|
||||
inline std::istream& operator>>(std::istream& i, BigInt& x) {
|
||||
x.makeCopy();
|
||||
//return CORE::operator>>(i, x.get_mp());
|
||||
return CORE::io_read(i, x.get_mp());
|
||||
}
|
||||
|
||||
/// sign
|
||||
inline int sign(const BigInt& a) {
|
||||
return mpz_sgn(a.get_mp());
|
||||
}
|
||||
/// abs
|
||||
inline BigInt abs(const BigInt& a) {
|
||||
BigInt r;
|
||||
mpz_abs(r.get_mp(), a.get_mp());
|
||||
return r;
|
||||
}
|
||||
/// neg
|
||||
inline BigInt neg(const BigInt& a) {
|
||||
BigInt r;
|
||||
mpz_neg(r.get_mp(), a.get_mp());
|
||||
return r;
|
||||
}
|
||||
/// negate
|
||||
inline void negate(BigInt& a) {
|
||||
a.makeCopy();
|
||||
mpz_neg(a.get_mp(), a.get_mp());
|
||||
}
|
||||
/// cmpabs
|
||||
inline int cmpabs(const BigInt& a, const BigInt& b) {
|
||||
return mpz_cmpabs(a.get_mp(), b.get_mp());
|
||||
}
|
||||
inline int set_str(BigInt& a, const char* s) {
|
||||
a = BigInt(s);
|
||||
return 0; // should be -1 if not correct in the base (we ignore)
|
||||
}
|
||||
|
||||
/// \name Conversion Functions
|
||||
//@{
|
||||
/// longValue
|
||||
/// longValue
|
||||
inline long longValue(const BigInt& a) {
|
||||
return a.longValue();
|
||||
return a.convert_to<long>();
|
||||
}
|
||||
/// ulongValue
|
||||
inline unsigned long ulongValue(const BigInt& a) {
|
||||
return a.ulongValue();
|
||||
}
|
||||
/// doubleValue
|
||||
|
||||
/// doubleValue
|
||||
inline double doubleValue(const BigInt& a) {
|
||||
return a.doubleValue();
|
||||
return a.convert_to<double>();
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name File I/O Functions
|
||||
//@{
|
||||
/// read from file
|
||||
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);
|
||||
//@}
|
||||
|
||||
/// \name Misc Functions
|
||||
//@{
|
||||
/// isEven
|
||||
/// isEven
|
||||
inline bool isEven(const BigInt& z) {
|
||||
return mpz_even_p(z.get_mp());
|
||||
return bit_test(z,0) == 0;
|
||||
}
|
||||
/// isOdd
|
||||
inline bool isOdd(const BigInt& z) {
|
||||
return mpz_odd_p(z.get_mp());
|
||||
return bit_test(z,0) == 1;
|
||||
}
|
||||
|
||||
/// get exponent of power 2
|
||||
inline unsigned long getBinExpo(const BigInt& z) {
|
||||
return mpz_scan1(z.get_mp(), 0);
|
||||
}
|
||||
/// get exponent of power k
|
||||
inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long k) {
|
||||
mpz_t f;
|
||||
mpz_init_set_ui(f, k);
|
||||
m.makeCopy();
|
||||
e = mpz_remove(m.get_mp(), z.get_mp(), f);
|
||||
mpz_clear(f);
|
||||
}
|
||||
|
||||
/// divisible(x,y) = "x | y"
|
||||
inline bool isDivisible(const BigInt& x, const BigInt& y) {
|
||||
return mpz_divisible_p(x.get_mp(), y.get_mp()) != 0;
|
||||
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;
|
||||
|
||||
}
|
||||
/// exact div
|
||||
/// get exponent of power 2
|
||||
inline std::size_t getBinExpo(const BigInt& z) {
|
||||
if (z.is_zero()) {
|
||||
return (std::numeric_limits<std::size_t>::max)();
|
||||
}
|
||||
return lsb(abs(z));
|
||||
}
|
||||
|
||||
// bit length
|
||||
inline std::size_t 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) {
|
||||
assert(std::size_t((std::numeric_limits<long>::max)()) > bitLength(a));
|
||||
return (sign(a) == 0) ? (-1) : static_cast<long>(bitLength(a)-1);
|
||||
}
|
||||
|
||||
|
||||
/// div_rem
|
||||
inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) {
|
||||
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) {
|
||||
z.makeCopy();
|
||||
mpz_divexact(z.get_mp(), x.get_mp(), y.get_mp());
|
||||
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) {
|
||||
|
|
@ -473,50 +138,19 @@ inline BigInt div_exact(const BigInt& x, const BigInt& 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)
|
||||
}
|
||||
|
||||
|
||||
/// gcd
|
||||
inline BigInt gcd(const BigInt& a, const BigInt& b) {
|
||||
BigInt r;
|
||||
mpz_gcd(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
/// div_rem
|
||||
inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) {
|
||||
q.makeCopy();
|
||||
r.makeCopy();
|
||||
mpz_tdiv_qr(q.get_mp(), r.get_mp(), a.get_mp(), b.get_mp());
|
||||
}
|
||||
/// power
|
||||
inline void power(BigInt& c, const BigInt& a, unsigned long ul) {
|
||||
c.makeCopy();
|
||||
mpz_pow_ui(c.get_mp(), a.get_mp(), ul);
|
||||
inline BigInt gcd(const BigInt& a, const BigInt& b){
|
||||
return boost::multiprecision::gcd(a,b);
|
||||
}
|
||||
|
||||
// pow
|
||||
inline BigInt pow(const BigInt& a, unsigned long ui) {
|
||||
BigInt r;
|
||||
power(r, a, ui);
|
||||
return r;
|
||||
}
|
||||
|
||||
// bit length
|
||||
inline int bitLength(const BigInt& a) {
|
||||
return mpz_sizeinbase(a.get_mp(), 2);
|
||||
}
|
||||
/// 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);
|
||||
}
|
||||
/// 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.
|
||||
|
|
@ -524,20 +158,45 @@ inline long floorLg(const BigInt& a) {
|
|||
inline long ceilLg(const BigInt& a) {
|
||||
if (sign(a) == 0)
|
||||
return -1;
|
||||
unsigned long len = bitLength(a);
|
||||
return (mpz_scan1(a.get_mp(), 0) == len-1) ? (len-1) : len;
|
||||
assert(std::size_t((std::numeric_limits<long>::max)()) > bitLength(a));
|
||||
std::size_t len = static_cast<long>(bitLength(a));
|
||||
|
||||
return (lsb(abs(a)) == len - 1) ? (static_cast<long>(len) - 1) : static_cast<long>(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) {
|
||||
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;
|
||||
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) {
|
||||
c = pow(a, ul);
|
||||
}
|
||||
|
||||
} // namespace CORE
|
||||
|
||||
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#endif // _CORE_BIGINT_H_
|
||||
|
|
|
|||
|
|
@ -28,354 +28,35 @@
|
|||
#include <CGAL/CORE/BigInt.h>
|
||||
|
||||
namespace CORE {
|
||||
#ifdef CGAL_CORE_USE_GMP_BACKEND
|
||||
typedef boost::multiprecision::mpq_rational BigRat;
|
||||
#else
|
||||
typedef boost::multiprecision::cpp_rational BigRat;
|
||||
#endif
|
||||
|
||||
class BigRatRep : public RCRepImpl<BigRatRep> {
|
||||
public:
|
||||
BigRatRep() {
|
||||
mpq_init(mp);
|
||||
}
|
||||
// Note : should the copy-ctor be allowed at all ? [Sylvain Pion]
|
||||
BigRatRep(const BigRatRep& z) : RCRepImpl<BigRatRep>() {
|
||||
mpq_init(mp);
|
||||
mpq_set(mp, z.mp);
|
||||
}
|
||||
BigRatRep(signed char c) {
|
||||
mpq_init(mp);
|
||||
mpq_set_si(mp, c, 1);
|
||||
}
|
||||
BigRatRep(unsigned char c) {
|
||||
mpq_init(mp);
|
||||
mpq_set_ui(mp, c, 1);
|
||||
}
|
||||
BigRatRep(signed int i) {
|
||||
mpq_init(mp);
|
||||
mpq_set_si(mp, i, 1);
|
||||
}
|
||||
BigRatRep(unsigned int i) {
|
||||
mpq_init(mp);
|
||||
mpq_set_ui(mp, i, 1);
|
||||
}
|
||||
BigRatRep(signed short int s) {
|
||||
mpq_init(mp);
|
||||
mpq_set_si(mp, s, 1);
|
||||
}
|
||||
BigRatRep(unsigned short int s) {
|
||||
mpq_init(mp);
|
||||
mpq_set_ui(mp, s, 1);
|
||||
}
|
||||
BigRatRep(signed long int l) {
|
||||
mpq_init(mp);
|
||||
mpq_set_si(mp, l, 1);
|
||||
}
|
||||
BigRatRep(unsigned long int l) {
|
||||
mpq_init(mp);
|
||||
mpq_set_ui(mp, l, 1);
|
||||
}
|
||||
BigRatRep(float f) {
|
||||
mpq_init(mp);
|
||||
mpq_set_d(mp, f);
|
||||
}
|
||||
BigRatRep(double d) {
|
||||
mpq_init(mp);
|
||||
mpq_set_d(mp, d);
|
||||
}
|
||||
BigRatRep(const char* s) {
|
||||
mpq_init(mp);
|
||||
mpq_set_str(mp, s, 0);
|
||||
}
|
||||
BigRatRep(const std::string& s) {
|
||||
mpq_init(mp);
|
||||
mpq_set_str(mp, s.c_str(), 0);
|
||||
}
|
||||
explicit BigRatRep(mpq_srcptr q) {
|
||||
mpq_init(mp);
|
||||
mpq_set(mp, q);
|
||||
}
|
||||
BigRatRep(mpz_srcptr z) {
|
||||
mpq_init(mp);
|
||||
mpq_set_z(mp, z);
|
||||
}
|
||||
BigRatRep(mpz_srcptr n, mpz_srcptr d) {
|
||||
mpq_init(mp);
|
||||
mpz_set(mpq_numref(mp), n);
|
||||
mpz_set(mpq_denref(mp), d);
|
||||
mpq_canonicalize(mp);
|
||||
}
|
||||
~BigRatRep() {
|
||||
mpq_clear(mp);
|
||||
|
||||
inline BigInt numerator(const BigRat& q)
|
||||
{
|
||||
return boost::multiprecision::numerator(q);
|
||||
}
|
||||
|
||||
CGAL_CORE_EXPORT CORE_NEW(BigRatRep)
|
||||
CGAL_CORE_EXPORT CORE_DELETE(BigRatRep)
|
||||
|
||||
mpq_srcptr get_mp() const {
|
||||
return mp;
|
||||
}
|
||||
mpq_ptr get_mp() {
|
||||
return mp;
|
||||
}
|
||||
private:
|
||||
mpq_t mp;
|
||||
}; //BigRatRep
|
||||
|
||||
class BigFloat;
|
||||
|
||||
typedef RCImpl<BigRatRep> RCBigRat;
|
||||
class BigRat : public RCBigRat {
|
||||
public:
|
||||
/// \name Constructors
|
||||
//@{
|
||||
/// default constructor
|
||||
BigRat() : RCBigRat(new BigRatRep()) {}
|
||||
/// constructor for <tt>signed char</tt>
|
||||
BigRat(signed char x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>unsigned char</tt>
|
||||
BigRat(unsigned char x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>signed short int</tt>
|
||||
BigRat(signed short int x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>unsigned short int</tt>
|
||||
BigRat(unsigned short int x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>signed int</tt>
|
||||
BigRat(signed int x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>unsigned int</tt>
|
||||
BigRat(unsigned int x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>signed long int</tt>
|
||||
BigRat(signed long int x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>unsigned long int</tt>
|
||||
BigRat(unsigned long int x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>float</tt>
|
||||
BigRat(float x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>double</tt>
|
||||
BigRat(double x) : RCBigRat(new BigRatRep(x)) {}
|
||||
/// constructor for <tt>const char*</tt> with base
|
||||
BigRat(const char* s) : RCBigRat(new BigRatRep(s)) {}
|
||||
/// constructor for <tt>std::string</tt> with base
|
||||
BigRat(const std::string& s) : RCBigRat(new BigRatRep(s)) {}
|
||||
/// constructor for <tt>mpq_srcptr</tt>
|
||||
explicit BigRat(mpq_srcptr z) : RCBigRat(new BigRatRep(z)) {}
|
||||
/// constructor for <tt>BigInt</tt>
|
||||
BigRat(const BigInt& z) : RCBigRat(new BigRatRep(z.get_mp())) {}
|
||||
/// constructor for two <tt>BigInts</tt>
|
||||
BigRat(const BigInt& n, const BigInt& d)
|
||||
: RCBigRat(new BigRatRep(n.get_mp(), d.get_mp())) {}
|
||||
/// constructor for <tt>BigFloat</tt>
|
||||
BigRat(const BigFloat&);
|
||||
//@}
|
||||
|
||||
/// \name Copy-Assignment-Destructor
|
||||
//@{
|
||||
/// copy constructor
|
||||
BigRat(const BigRat& rhs) : RCBigRat(rhs) {
|
||||
rep->incRef();
|
||||
}
|
||||
/// assignment operator
|
||||
BigRat& operator=(const BigRat& rhs) {
|
||||
if (this != &rhs) {
|
||||
rep->decRef();
|
||||
rep = rhs.rep;
|
||||
rep->incRef();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
/// destructor
|
||||
~BigRat() {
|
||||
rep->decRef();
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name Overloaded operators
|
||||
//@{
|
||||
BigRat& operator +=(const BigRat& rhs) {
|
||||
makeCopy();
|
||||
mpq_add(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigRat& operator -=(const BigRat& rhs) {
|
||||
makeCopy();
|
||||
mpq_sub(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigRat& operator *=(const BigRat& rhs) {
|
||||
makeCopy();
|
||||
mpq_mul(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigRat& operator /=(const BigRat& rhs) {
|
||||
makeCopy();
|
||||
mpq_div(get_mp(), get_mp(), rhs.get_mp());
|
||||
return *this;
|
||||
}
|
||||
BigRat& operator <<=(unsigned long ul) {
|
||||
makeCopy();
|
||||
mpq_mul_2exp(get_mp(), get_mp(), ul);
|
||||
return *this;
|
||||
}
|
||||
BigRat& operator >>=(unsigned long ul) {
|
||||
makeCopy();
|
||||
mpq_div_2exp(get_mp(), get_mp(), ul);
|
||||
return *this;
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name div2, unary, increment, decrement operators
|
||||
//@{
|
||||
|
||||
/// exact division by 2 (this method is provided for compatibility)
|
||||
BigRat div2() const {
|
||||
BigRat r; BigRat t(2); // probably not most efficient way
|
||||
mpq_div(r.get_mp(), get_mp(), t.get_mp());
|
||||
return r;
|
||||
}
|
||||
BigRat operator+() const {
|
||||
return BigRat(*this);
|
||||
}
|
||||
BigRat operator-() const {
|
||||
BigRat r;
|
||||
mpq_neg(r.get_mp(), get_mp());
|
||||
return r;
|
||||
}
|
||||
BigRat& operator++() {
|
||||
makeCopy();
|
||||
mpz_add(get_num_mp(),get_num_mp(),get_den_mp());
|
||||
return *this;
|
||||
}
|
||||
BigRat& operator--() {
|
||||
makeCopy();
|
||||
mpz_sub(get_num_mp(),get_num_mp(),get_den_mp());
|
||||
return *this;
|
||||
}
|
||||
BigRat operator++(int) {
|
||||
BigRat r(*this);
|
||||
++(*this);
|
||||
return r;
|
||||
}
|
||||
BigRat operator--(int) {
|
||||
BigRat r(*this);
|
||||
--(*this);
|
||||
return r;
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name Helper Functions
|
||||
//@{
|
||||
/// Canonicalize
|
||||
void canonicalize() {
|
||||
makeCopy();
|
||||
mpq_canonicalize(get_mp());
|
||||
}
|
||||
/// Has Exact Division
|
||||
static bool hasExactDivision() {
|
||||
return true;
|
||||
inline BigInt denominator(const BigRat& q)
|
||||
{
|
||||
return boost::multiprecision::denominator(q);
|
||||
}
|
||||
|
||||
/// return mpz pointer of numerator (const)
|
||||
mpz_srcptr get_num_mp() const {
|
||||
return mpq_numref(get_mp());
|
||||
}
|
||||
/// return mpz pointer of numerator
|
||||
mpz_ptr get_num_mp() {
|
||||
return mpq_numref(get_mp());
|
||||
}
|
||||
/// return mpz pointer of denominator
|
||||
mpz_srcptr get_den_mp() const {
|
||||
return mpq_denref(get_mp());
|
||||
}
|
||||
/// return mpz pointer of denominator
|
||||
mpz_ptr get_den_mp() {
|
||||
return mpq_denref(get_mp());
|
||||
}
|
||||
|
||||
/// get mpq pointer (const)
|
||||
mpq_srcptr get_mp() const {
|
||||
return rep->get_mp();
|
||||
}
|
||||
/// get mpq pointer
|
||||
mpq_ptr get_mp() {
|
||||
return rep->get_mp();
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name String Conversion Functions
|
||||
//@{
|
||||
/// set value from <tt>const char*</tt>
|
||||
int set_str(const char* s, int base = 0) {
|
||||
makeCopy();
|
||||
return mpq_set_str(get_mp(), s, base);
|
||||
}
|
||||
/// convert to <tt>std::string</tt>
|
||||
std::string get_str(int base = 10) const {
|
||||
int n = mpz_sizeinbase(mpq_numref(get_mp()), base) + mpz_sizeinbase(mpq_denref(get_mp()), base)+ 3;
|
||||
char *buffer = new char[n];
|
||||
mpq_get_str(buffer, base, get_mp());
|
||||
std::string result(buffer);
|
||||
delete [] buffer;
|
||||
return result;
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \name Conversion Functions
|
||||
//@{
|
||||
/// intValue
|
||||
int intValue() const {
|
||||
return static_cast<int>(doubleValue());
|
||||
}
|
||||
/// longValue
|
||||
long longValue() const {
|
||||
return static_cast<long>(doubleValue());
|
||||
}
|
||||
/// doubleValue
|
||||
double doubleValue() const {
|
||||
return mpq_get_d(get_mp());
|
||||
}
|
||||
/// BigIntValue
|
||||
BigInt BigIntValue() const {
|
||||
BigInt r;
|
||||
mpz_tdiv_q(r.get_mp(), get_num_mp(), get_den_mp());
|
||||
return r;
|
||||
}
|
||||
//@}
|
||||
}; //BigRat class
|
||||
|
||||
inline BigRat operator+(const BigRat& a, const BigRat& b) {
|
||||
BigRat r;
|
||||
mpq_add(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigRat operator-(const BigRat& a, const BigRat& b) {
|
||||
BigRat r;
|
||||
mpq_sub(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigRat operator*(const BigRat& a, const BigRat& b) {
|
||||
BigRat r;
|
||||
mpq_mul(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
inline BigRat operator/(const BigRat& a, const BigRat& b) {
|
||||
BigRat r;
|
||||
mpq_div(r.get_mp(), a.get_mp(), b.get_mp());
|
||||
return r;
|
||||
}
|
||||
// Chee (3/19/2004):
|
||||
// Chee (3/19/2004):
|
||||
// The following definitions of div_exact(x,y) and gcd(x,y)
|
||||
// ensures that in Polynomial<NT>
|
||||
/// divisible(x,y) = "x | y"
|
||||
inline BigRat div_exact(const BigRat& x, const BigRat& y) {
|
||||
BigRat z;
|
||||
mpq_div(z.get_mp(), x.get_mp(), y.get_mp());
|
||||
return z;
|
||||
}
|
||||
/// numerator
|
||||
inline BigInt numerator(const BigRat& a) {
|
||||
return BigInt(a.get_num_mp());
|
||||
}
|
||||
/// denominator
|
||||
inline BigInt denominator(const BigRat& a) {
|
||||
return BigInt(a.get_den_mp());
|
||||
}
|
||||
inline BigRat div_exact(const BigRat& x, const BigRat& y) {
|
||||
BigRat z = x / y;
|
||||
return z;
|
||||
}
|
||||
|
||||
inline BigRat gcd(const BigRat& x, const BigRat& y) {
|
||||
// return BigRat(1); // Remark: we may want replace this by
|
||||
inline BigRat gcd(const BigRat& x , const BigRat& y)
|
||||
{
|
||||
// return BigRat(1); // Remark: we may want replace this by
|
||||
// the definition of gcd of a quotient field
|
||||
// of a UFD [Yap's book, Chap.3]
|
||||
//Here is one possible definition: gcd of x and y is just the
|
||||
|
|
@ -384,98 +65,17 @@ inline BigRat gcd(const BigRat& x, const BigRat& y) {
|
|||
BigInt n = gcd(numerator(x), numerator(y));
|
||||
BigInt d = gcd(denominator(x), denominator(y));
|
||||
return BigRat(n,d);
|
||||
}
|
||||
|
||||
}
|
||||
// Chee: 8/8/2004: need isDivisible to compile Polynomial<BigRat>
|
||||
// A trivial implementation is to return true always. But this
|
||||
// caused tPolyRat to fail.
|
||||
// So we follow the definition of
|
||||
// Expr::isDivisible(e1, e2) which checks if e1/e2 is an integer.
|
||||
inline bool isInteger(const BigRat& x) {
|
||||
return BigInt(x.get_den_mp()) == 1;
|
||||
}
|
||||
inline bool isDivisible(const BigRat& x, const BigRat& y) {
|
||||
BigRat r;
|
||||
mpq_div(r.get_mp(), x.get_mp(), y.get_mp());
|
||||
return isInteger(r);
|
||||
}
|
||||
inline BigRat operator<<(const BigRat& a, unsigned long ul) {
|
||||
BigRat r;
|
||||
mpq_mul_2exp(r.get_mp(), a.get_mp(), ul);
|
||||
return r;
|
||||
}
|
||||
inline BigRat operator>>(const BigRat& a, unsigned long ul) {
|
||||
BigRat r;
|
||||
mpq_div_2exp(r.get_mp(), a.get_mp(), ul);
|
||||
/// BigIntValue
|
||||
inline BigInt BigIntValue(const BigRat& br)
|
||||
{
|
||||
BigInt r, rem;
|
||||
divide_qr(numerator(br), denominator(br), r, rem);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline int cmp(const BigRat& x, const BigRat& y) {
|
||||
return mpq_cmp(x.get_mp(), y.get_mp());
|
||||
}
|
||||
inline bool operator==(const BigRat& a, const BigRat& b) {
|
||||
return cmp(a, b) == 0;
|
||||
}
|
||||
inline bool operator!=(const BigRat& a, const BigRat& b) {
|
||||
return cmp(a, b) != 0;
|
||||
}
|
||||
inline bool operator>=(const BigRat& a, const BigRat& b) {
|
||||
return cmp(a, b) >= 0;
|
||||
}
|
||||
inline bool operator>(const BigRat& a, const BigRat& b) {
|
||||
return cmp(a, b) > 0;
|
||||
}
|
||||
inline bool operator<=(const BigRat& a, const BigRat& b) {
|
||||
return cmp(a, b) <= 0;
|
||||
}
|
||||
inline bool operator<(const BigRat& a, const BigRat& b) {
|
||||
return cmp(a, b) < 0;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& o, const BigRat& x) {
|
||||
//return CORE::operator<<(o, x.get_mp());
|
||||
return CORE::io_write(o, x.get_mp());
|
||||
}
|
||||
inline std::istream& operator>>(std::istream& i, BigRat& x) {
|
||||
x.makeCopy();
|
||||
//return CORE::operator>>(i, x.get_mp());
|
||||
return CORE::io_read(i, x.get_mp());
|
||||
}
|
||||
|
||||
/// sign
|
||||
inline int sign(const BigRat& a) {
|
||||
return mpq_sgn(a.get_mp());
|
||||
}
|
||||
/// abs
|
||||
inline BigRat abs(const BigRat& a) {
|
||||
BigRat r;
|
||||
mpq_abs(r.get_mp(), a.get_mp());
|
||||
return r;
|
||||
}
|
||||
/// neg
|
||||
inline BigRat neg(const BigRat& a) {
|
||||
BigRat r;
|
||||
mpq_neg(r.get_mp(), a.get_mp());
|
||||
return r;
|
||||
}
|
||||
/// div2
|
||||
inline BigRat div2(const BigRat& a) {
|
||||
BigRat r(a);
|
||||
return r.div2();
|
||||
}
|
||||
/// longValue
|
||||
inline long longValue(const BigRat& a) {
|
||||
return a.longValue();
|
||||
}
|
||||
/// doubleValue
|
||||
inline double doubleValue(const BigRat& a) {
|
||||
return a.doubleValue();
|
||||
}
|
||||
/// return BigInt value
|
||||
inline BigInt BigIntValue(const BigRat& a) {
|
||||
return a.BigIntValue();
|
||||
}
|
||||
} // namespace CORE
|
||||
|
||||
|
||||
} //namespace CORE
|
||||
#endif // _CORE_BIGRAT_H_
|
||||
|
|
|
|||
|
|
@ -29,4 +29,13 @@
|
|||
|
||||
#include <CGAL/export/CORE.h>
|
||||
|
||||
#ifdef CGAL_TEST_SUITE
|
||||
// disabled for the testsuite to avoid `w`
|
||||
#define CGAL_CORE_warning_msg(X ,Y)
|
||||
// if (!(X)) CGAL_error_msg(Y)
|
||||
#else
|
||||
#define CGAL_CORE_warning_msg(X ,Y) CGAL_warning_msg(X ,Y)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _CORE_CONFIG_H_
|
||||
|
|
|
|||
|
|
@ -156,12 +156,6 @@ CGAL_CORE_EXPORT double IntMantissa(double d);
|
|||
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
|
||||
CGAL_CORE_EXPORT int IntExponent(double d);
|
||||
|
||||
/// Writes out an error or warning message in the local file CORE_DIAGFILE
|
||||
/** If last argument (err) is TRUE, then this is considered an error
|
||||
* (not just warning). In this case, the message is also printed in
|
||||
* std::cerr, using std::perror().
|
||||
* */
|
||||
CGAL_CORE_EXPORT void core_error(std::string msg, std::string file, int lineno, bool err);
|
||||
|
||||
/// This is for debugging messages
|
||||
inline void core_debug(std::string msg){
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
#include <CGAL/use.h>
|
||||
#include <CGAL/CORE/CoreAux.h>
|
||||
#include <CGAL/gmp.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
|
|
@ -157,30 +156,5 @@ int IntExponent(double d) {
|
|||
return e-53;
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
|
||||
+ std::to_string(lineno) +"):" + msg + "\n").c_str();
|
||||
std::exit(1); //Note: do not call abort()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace CORE
|
||||
|
|
|
|||
|
|
@ -1,479 +0,0 @@
|
|||
/****************************************************************************
|
||||
* Core Library Version 1.7, August 2004
|
||||
* Copyright (c) 1995-2004 Exact Computation Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of CGAL (www.cgal.org).
|
||||
*
|
||||
* File: CoreIO.cpp
|
||||
*
|
||||
* Written by
|
||||
* Zilin Du <zilin@cs.nyu.edu>
|
||||
* Chee Yap <yap@cs.nyu.edu>
|
||||
*
|
||||
* WWW URL: https://cs.nyu.edu/exact/
|
||||
* Email: exact@cs.nyu.edu
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _COREIO_IMPL_H_
|
||||
#define _COREIO_IMPL_H_
|
||||
|
||||
#ifdef CGAL_HEADER_ONLY
|
||||
#define CGAL_INLINE_FUNCTION inline
|
||||
#else
|
||||
#define CGAL_INLINE_FUNCTION
|
||||
#endif
|
||||
|
||||
#include <CGAL/CORE/BigFloatRep.h>
|
||||
#include <CGAL/CORE/BigFloat.h>
|
||||
#include <CGAL/CORE/BigInt.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
CGAL_INLINE_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_INLINE_FUNCTION
|
||||
void core_io_memory_handler(char *t, const char *f, const char *m) {
|
||||
if (t == nullptr) {
|
||||
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_INLINE_FUNCTION
|
||||
void allocate (char * &s, int old_size, int new_size) {
|
||||
if (old_size > new_size)
|
||||
old_size = new_size;
|
||||
|
||||
if (s == nullptr)
|
||||
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_INLINE_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_INLINE_FUNCTION
|
||||
int skip_comment_line (std::istream & in) {
|
||||
char c;
|
||||
|
||||
do {
|
||||
in.get(c);
|
||||
while ( c == '#' ) {
|
||||
do {
|
||||
in.get(c);
|
||||
} while ( c != '\n' );
|
||||
in.get(c);
|
||||
}
|
||||
} while (c == ' ' || c == '\t' || c == '\n');
|
||||
|
||||
if (in.eof())
|
||||
core_io_error_handler("CoreIO::read_from_file()","unexpected end of file.");
|
||||
|
||||
in.putback(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
// skips '\\' followed by '\n'
|
||||
CGAL_INLINE_FUNCTION
|
||||
char skip_backslash_new_line (std::istream & in) {
|
||||
char c;
|
||||
in.get(c);
|
||||
|
||||
while (c == '\\') {
|
||||
in.get(c);
|
||||
|
||||
if (c == '\n')
|
||||
in.get(c);
|
||||
else
|
||||
core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line.");
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
void read_string(std::istream& in, char* &buffer, int sz) {
|
||||
char c;
|
||||
int pos=0;
|
||||
skip_comment_line(in);
|
||||
|
||||
while ( in.get(c) ) {
|
||||
if ( c == ' ' || c == '\t' || c == '\n' || c == '#')
|
||||
break;
|
||||
else
|
||||
append_char(buffer, sz, pos++, c);
|
||||
}
|
||||
append_char(buffer, sz, pos, '\0');
|
||||
}
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
|
||||
char *buffer;
|
||||
int size, offset;
|
||||
int base;
|
||||
bool is_negate;
|
||||
|
||||
char c;
|
||||
int pos = 0;
|
||||
skip_comment_line(in);
|
||||
|
||||
// read sign
|
||||
in.get(c);
|
||||
if (c == '-') {
|
||||
is_negate = true;
|
||||
in.get(c);
|
||||
} else
|
||||
is_negate = false;
|
||||
|
||||
// read base and compute digits
|
||||
if (c == '0') {
|
||||
in.get(c);
|
||||
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; i++) {
|
||||
c=skip_backslash_new_line(in);
|
||||
if(in.eof()){
|
||||
break;
|
||||
}
|
||||
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 necessary
|
||||
if (offset > 0 && base != 10) {
|
||||
m <<= offset;
|
||||
}
|
||||
|
||||
if (is_negate)
|
||||
negate(m);
|
||||
}
|
||||
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
void write_base_number(std::ostream& out, char* buffer, std::size_t 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 (std::size_t 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 absolute value string
|
||||
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
|
||||
mpz_get_str(buffer, base, c.get_mp());
|
||||
std::size_t 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 absolute value string
|
||||
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
|
||||
mpz_get_str(buffer, base, c.get_mp());
|
||||
std::size_t 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_
|
||||
|
|
@ -72,9 +72,7 @@ public:
|
|||
Expr(float f) : RCExpr(nullptr) { // check for valid numbers
|
||||
// (i.e., not infinite and not NaN)
|
||||
if (! CGAL_CORE_finite(f)) {
|
||||
core_error(" ERROR : constructed an invalid float! ", __FILE__, __LINE__, false);
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
CGAL_error_msg("ERROR : constructed an invalid float! ");
|
||||
get_static_InvalidFlag() = -1;
|
||||
}
|
||||
rep = new ConstDoubleRep(f);
|
||||
|
|
@ -83,9 +81,7 @@ public:
|
|||
Expr(double d) : RCExpr(nullptr) { // check for valid numbers
|
||||
// (i.e., not infinite and not NaN)
|
||||
if (! CGAL_CORE_finite(d)) {
|
||||
core_error(" ERROR : constructed an invalid double! ", __FILE__, __LINE__, false);
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
CGAL_error_msg("ERROR : constructed an invalid double! ");
|
||||
get_static_InvalidFlag() = -2;
|
||||
}
|
||||
rep = new ConstDoubleRep(d);
|
||||
|
|
@ -95,6 +91,14 @@ public:
|
|||
Expr(const BigInt& I) : RCExpr(new ConstRealRep(Real(I))) {}
|
||||
/// constructor for <tt>BigRat</tt>
|
||||
Expr(const BigRat& R) : RCExpr(new ConstRealRep(Real(R))) {}
|
||||
/// constructor from expression template
|
||||
template <class TmplExpr,
|
||||
class = std::enable_if_t<
|
||||
boost::multiprecision::is_number_expression<TmplExpr>::value> >
|
||||
Expr(const TmplExpr& R)
|
||||
: RCExpr(new ConstRealRep(Real(
|
||||
std::conditional_t<boost::multiprecision::number_category<TmplExpr>::value == boost::multiprecision::number_kind_integer,
|
||||
BigInt, BigRat>(R)))) {}
|
||||
|
||||
/// constructor for <tt>BigFloat</tt>
|
||||
Expr(const BigFloat& F) : RCExpr(new ConstRealRep(Real(F))) {}
|
||||
|
|
@ -173,9 +177,7 @@ public:
|
|||
/// /= operator
|
||||
Expr& operator/=(const Expr& e) {
|
||||
if ((e.rep)->getSign() == 0) {
|
||||
core_error(" ERROR : division by zero ! ",__FILE__, __LINE__, false);
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
CGAL_error_msg("ERROR : division by zero ! ");
|
||||
get_static_InvalidFlag() = -3;
|
||||
}
|
||||
*this = new DivRep(rep, e.rep);
|
||||
|
|
@ -376,9 +378,7 @@ inline Expr operator*(const Expr& e1, const Expr& e2) {
|
|||
/// division
|
||||
inline Expr operator/(const Expr& e1, const Expr& e2) {
|
||||
if (e2.sign() == 0) {
|
||||
core_error(" ERROR : division by zero ! ", __FILE__, __LINE__, false);
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
CGAL_error_msg("ERROR : division by zero ! ");
|
||||
get_static_InvalidFlag() = -4;
|
||||
}
|
||||
return Expr(new DivRep(e1.Rep(), e2.Rep()));
|
||||
|
|
@ -479,9 +479,7 @@ inline bool isDivisible(const Expr& e1, const Expr& e2) {
|
|||
/// square root
|
||||
inline Expr sqrt(const Expr& e) {
|
||||
if (e.sign() < 0) {
|
||||
core_error(" ERROR : sqrt of negative value ! ", __FILE__, __LINE__, false);
|
||||
if (get_static_AbortFlag())
|
||||
abort();
|
||||
CGAL_error_msg("ERROR : sqrt of negative value ! ");
|
||||
get_static_InvalidFlag() = -5;
|
||||
}
|
||||
return Expr(new SqrtRep(e.Rep()));
|
||||
|
|
|
|||
|
|
@ -564,9 +564,7 @@ public:
|
|||
I = ss.isolateRoot(n);
|
||||
// check whether n-th root exists
|
||||
if (I.first == 1 && I.second == 0) {
|
||||
core_error("CORE ERROR! root index out of bound",
|
||||
__FILE__, __LINE__, true);
|
||||
abort();
|
||||
CGAL_error_msg("CORE ERROR! root index out of bound");
|
||||
}
|
||||
// test if the root isolated in I is 0:
|
||||
if ((I.first == 0)&&(I.second == 0))
|
||||
|
|
@ -583,9 +581,7 @@ public:
|
|||
ss.isolateRoots(I.first, I.second, v);
|
||||
I = v.front();
|
||||
if (v.size() != 1) {
|
||||
core_error("CORE ERROR! non-isolating interval",
|
||||
__FILE__, __LINE__, true);
|
||||
abort();
|
||||
CGAL_error_msg("CORE ERROR! non-isolating interval");
|
||||
}
|
||||
ffVal = computeFilteredValue(); // Chee: this line seems unnecessary
|
||||
}
|
||||
|
|
@ -1092,8 +1088,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
uMSB() = newValue.uMSB(); // chen: to get tighers value.
|
||||
sign() = newValue.sign();
|
||||
} else if (lowBound.isInfty()) {//check if rootbound is too big
|
||||
core_error("AddSubRep:root bound has exceeded the maximum size\n \
|
||||
but we still cannot decide zero.\n", __FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, "AddSubRep:root bound has exceeded the maximum size but we still cannot decide zero.");
|
||||
} else { // Op(first, second) == 0
|
||||
lMSB() = CORE_negInfty;
|
||||
sign() = 0;
|
||||
|
|
@ -1186,8 +1181,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
//8/9/01, Chee: implement escape precision here:
|
||||
if (i> get_static_EscapePrec()) {
|
||||
get_static_EscapePrecFlag() = -i.asLong();//negative means EscapePrec is used
|
||||
core_error("Escape precision triggered at",
|
||||
__FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, "Escape precision triggered");
|
||||
if (get_static_EscapePrecWarning())
|
||||
std::cout<< "Escape Precision triggered at "
|
||||
<< get_static_EscapePrec() << " bits" << std::endl;
|
||||
|
|
@ -1204,8 +1198,7 @@ void AddSubRep<Operator>::computeExactFlags() {
|
|||
#endif
|
||||
|
||||
if (sign() == 0 && ua .isInfty()) {
|
||||
core_error("AddSubRep: root bound has exceeded the maximum size\n \
|
||||
but we still cannot decide zero.\n", __FILE__, __LINE__, true);
|
||||
CGAL_error_msg("AddSubRep: root bound has exceeded the maximum size but we still cannot decide zero.");
|
||||
} // if (sign == 0 && ua .isInfty())
|
||||
}// else do progressive
|
||||
}
|
||||
|
|
@ -1236,8 +1229,7 @@ void AddSubRep<Operator>::computeApproxValue(const extLong& relPrec,
|
|||
{
|
||||
std::ostringstream oss;
|
||||
oss << "CORE WARNING: a huge lMSB in AddSubRep: " << lMSB();
|
||||
core_error(oss.str(),
|
||||
__FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, oss.str().c_str());
|
||||
}
|
||||
|
||||
extLong rf = first->uMSB()-lMSB()+relPrec+EXTLONG_FOUR; // 2 better
|
||||
|
|
|
|||
|
|
@ -702,7 +702,7 @@ void computeExactFlags_temp(ConstRep* t, const Real &value) {
|
|||
} else {
|
||||
t->uMSB() = value.uMSB();
|
||||
t->lMSB() = value.lMSB();
|
||||
core_error("Leaves in DAG is not exact!", __FILE__, __LINE__, true);
|
||||
CGAL_error_msg("Leafs in DAG is not exact!");
|
||||
}
|
||||
|
||||
t->sign() = value.sign();
|
||||
|
|
@ -809,8 +809,7 @@ void SqrtRep::computeExactFlags() {
|
|||
|
||||
sign() = child->sign();
|
||||
if (sign() < 0)
|
||||
core_error("squareroot is called with negative operand.",
|
||||
__FILE__, __LINE__, true);
|
||||
CGAL_error_msg("square root is called with negative operand.");
|
||||
|
||||
uMSB() = child->uMSB() / EXTLONG_TWO;
|
||||
lMSB() = child->lMSB() / EXTLONG_TWO;
|
||||
|
|
@ -928,7 +927,7 @@ void DivRep::computeExactFlags() {
|
|||
second->computeExactFlags();
|
||||
|
||||
if (!second->sign())
|
||||
core_error("zero divisor.", __FILE__, __LINE__, true);
|
||||
CGAL_error_msg("zero divisor.");
|
||||
|
||||
if (!first->sign()) {// value must be exactly zero.
|
||||
reduceToZero();
|
||||
|
|
@ -1025,8 +1024,7 @@ void MultRep::computeApproxValue(const extLong& relPrec,
|
|||
{
|
||||
std::ostringstream oss;
|
||||
oss << "CORE WARNING: a huge lMSB in AddSubRep " << lMSB();
|
||||
core_error(oss.str(),
|
||||
__FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, oss.str().c_str());
|
||||
}
|
||||
|
||||
extLong r = relPrec + EXTLONG_FOUR;
|
||||
|
|
@ -1048,8 +1046,7 @@ void DivRep::computeApproxValue(const extLong& relPrec,
|
|||
{
|
||||
std::ostringstream oss;
|
||||
oss << "CORE WARNING: a huge lMSB in AddSubRep " << lMSB();
|
||||
core_error(oss.str(),
|
||||
__FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, oss.str().c_str());
|
||||
}
|
||||
|
||||
extLong rr = relPrec + EXTLONG_SEVEN; // These rules come from
|
||||
|
|
@ -1082,7 +1079,9 @@ void Expr::debug(int mode, int level, int depthLimit) const {
|
|||
else if (mode == Expr::TREE_MODE)
|
||||
rep->debugTree(level, 0, depthLimit);
|
||||
else
|
||||
core_error("unknown debugging mode", __FILE__, __LINE__, false);
|
||||
{
|
||||
CGAL_CORE_warning_msg(false, "unknown debugging mode");
|
||||
}
|
||||
std::cout << "---- End Expr debug(): " << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -1215,8 +1214,6 @@ void BinOpRep::debugTree(int level, int indent, int depthLimit) const {
|
|||
second->debugTree(level, indent + 2, depthLimit - 1);
|
||||
}
|
||||
|
||||
CORE_MEMORY_IMPL(BigIntRep)
|
||||
CORE_MEMORY_IMPL(BigRatRep)
|
||||
CORE_MEMORY_IMPL(ConstDoubleRep)
|
||||
CORE_MEMORY_IMPL(ConstRealRep)
|
||||
|
||||
|
|
|
|||
|
|
@ -137,8 +137,8 @@ public:
|
|||
}
|
||||
/// division
|
||||
filteredFp operator/ (const filteredFp& x) const {
|
||||
if (x.fpVal == 0.0)
|
||||
core_error("possible zero divisor!", __FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(x.fpVal != 0.0, "possible zero divisor!");
|
||||
|
||||
double xxx = core_abs(x.fpVal) / x.maxAbs - (x.ind+1)*CORE_EPS + DBL_MIN;
|
||||
if (xxx > 0) {
|
||||
double val = fpVal / x.fpVal;
|
||||
|
|
@ -149,8 +149,8 @@ public:
|
|||
}
|
||||
/// square root
|
||||
filteredFp sqrt () const {
|
||||
if (fpVal < 0.0)
|
||||
core_error("possible negative sqrt!", __FILE__, __LINE__, false);
|
||||
|
||||
CGAL_CORE_warning_msg( !(fpVal < 0.0), "possible negative sqrt!");
|
||||
if (fpVal > 0.0) {
|
||||
double val = std::sqrt(fpVal);
|
||||
return filteredFp(val, ( maxAbs / fpVal ) * val, 1 + ind);
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
/****************************************************************************
|
||||
* Core Library Version 1.7, August 2004
|
||||
* Copyright (c) 1995-2004 Exact Computation Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of CGAL (www.cgal.org).
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
***************************************************************************/
|
||||
|
||||
// CORE LIBRARY FILE
|
||||
#ifndef _CORE_GMP_H_
|
||||
#define _CORE_GMP_H_
|
||||
|
||||
#include <CGAL/CORE/Impl.h>
|
||||
#include <gmp.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpz_srcptr);
|
||||
CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpq_srcptr);
|
||||
CGAL_CORE_EXPORT std::istream& io_read (std::istream &, mpz_ptr);
|
||||
CGAL_CORE_EXPORT std::istream& io_read (std::istream &, mpq_ptr);
|
||||
//std::ostream& operator<< (std::ostream &, mpz_srcptr);
|
||||
//std::ostream& operator<< (std::ostream &, mpq_srcptr);
|
||||
//std::istream& operator>> (std::istream &, mpz_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_
|
||||
|
|
@ -1,265 +0,0 @@
|
|||
/****************************************************************************
|
||||
* 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$
|
||||
* SPDX-License-Identifier: LGPL-3.0-only
|
||||
***************************************************************************/
|
||||
|
||||
/* Auxiliary functions for C++-style input of GMP types.
|
||||
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
CGAL_INLINE_FUNCTION
|
||||
int
|
||||
__gmp_istream_set_base (std::istream &i, char &c, bool &zero, bool &showbase)
|
||||
{
|
||||
int base;
|
||||
using std::ios;
|
||||
|
||||
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 (std::string &s, std::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
|
||||
std::istream &
|
||||
//operator>> (std::istream &i, mpz_ptr z)
|
||||
io_read (std::istream &i, mpz_ptr z)
|
||||
{
|
||||
using namespace std;
|
||||
int base;
|
||||
char c = 0;
|
||||
std::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
|
||||
std::istream &
|
||||
//operator>> (std::istream &i, mpq_ptr q)
|
||||
io_read (std::istream &i, mpq_ptr q)
|
||||
{
|
||||
using namespace std;
|
||||
int base;
|
||||
char c = 0;
|
||||
std::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 (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
|
||||
std::ostream&
|
||||
//operator<< (std::ostream &o, mpz_srcptr z)
|
||||
io_write (std::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
|
||||
std::ostream&
|
||||
//operator<< (std::ostream &o, mpq_srcptr q)
|
||||
io_write (std::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
|
||||
|
|
@ -57,7 +57,7 @@ public:
|
|||
t = t->next;
|
||||
}
|
||||
//);
|
||||
//CGAL_warning_msg(count == nObjects * blocks.size(),
|
||||
//CGAL_CORE_warning_msg(count == nObjects * blocks.size(),
|
||||
// "Cannot delete memory as there are cyclic references");
|
||||
|
||||
if(count == nObjects * blocks.size()){
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@
|
|||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __PROMOTE_H__
|
||||
#define __PROMOTE_H__
|
||||
#ifndef _CORE_PROMOTE_H__
|
||||
#define _CORE_PROMOTE_H__
|
||||
|
||||
#include <CGAL/CORE/Impl.h>
|
||||
#include <CGAL/CORE/BigInt.h>
|
||||
#include <CGAL/CORE/BigRat.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
|
|
@ -67,10 +69,10 @@ class Promotion<T, T> {
|
|||
typedef T ResultT;
|
||||
};
|
||||
|
||||
#define MAX_TYPE(T1, T2) \
|
||||
#define CORE_MAX_TYPE(T1, T2) \
|
||||
typename Promotion<T1, T2>::ResultT
|
||||
|
||||
#define DEFINE_MAX_TYPE(T1, T2, Tr) \
|
||||
#define CORE_DEFINE_MAX_TYPE(T1, T2, Tr) \
|
||||
template<> class Promotion<T1, T2> { \
|
||||
public: \
|
||||
typedef Tr ResultT; \
|
||||
|
|
@ -83,15 +85,15 @@ class Promotion<T, T> {
|
|||
/*
|
||||
* For example:
|
||||
*
|
||||
* DEFINE_MAX_TYPE(BigInt, BigRat, BigRat) // define the promotion
|
||||
* CORE_DEFINE_MAX_TYPE(BigInt, BigRat, BigRat) // define the promotion
|
||||
*
|
||||
* template<typename T1, typename T2> // define function f with type templates
|
||||
* MAX_TYPE(T1, T2) f(T1& , T2& );
|
||||
* CORE_MAX_TYPE(T1, T2) f(T1& , T2& );
|
||||
*
|
||||
* or
|
||||
*
|
||||
* template<typename T1, typename T2> // define function f with type templates
|
||||
* const MAX_TYPE(T1, T2)& f(T1& , T2& );
|
||||
* const CORE_MAX_TYPE(T1, T2)& f(T1& , T2& );
|
||||
*
|
||||
* BigInt a = 1;
|
||||
* BigRat b = "1/3";
|
||||
|
|
@ -119,30 +121,30 @@ class Promotion<T, T> {
|
|||
*
|
||||
*/
|
||||
|
||||
class BigInt;
|
||||
//class BigInt;
|
||||
class BigFloat;
|
||||
class BigRat;
|
||||
//class BigRat;
|
||||
class Expr;
|
||||
|
||||
DEFINE_MAX_TYPE(long, BigInt, BigInt)
|
||||
DEFINE_MAX_TYPE(long, BigFloat, BigFloat)
|
||||
DEFINE_MAX_TYPE(long, BigRat, BigRat)
|
||||
DEFINE_MAX_TYPE(long, Expr, Expr)
|
||||
CORE_DEFINE_MAX_TYPE(long, BigInt, BigInt)
|
||||
CORE_DEFINE_MAX_TYPE(long, BigFloat, BigFloat)
|
||||
CORE_DEFINE_MAX_TYPE(long, BigRat, BigRat)
|
||||
CORE_DEFINE_MAX_TYPE(long, Expr, Expr)
|
||||
|
||||
DEFINE_MAX_TYPE(int, BigInt, BigInt)
|
||||
DEFINE_MAX_TYPE(int, BigFloat, BigFloat)
|
||||
DEFINE_MAX_TYPE(int, BigRat, BigRat)
|
||||
DEFINE_MAX_TYPE(int, Expr, Expr)
|
||||
CORE_DEFINE_MAX_TYPE(int, BigInt, BigInt)
|
||||
CORE_DEFINE_MAX_TYPE(int, BigFloat, BigFloat)
|
||||
CORE_DEFINE_MAX_TYPE(int, BigRat, BigRat)
|
||||
CORE_DEFINE_MAX_TYPE(int, Expr, Expr)
|
||||
|
||||
DEFINE_MAX_TYPE(BigInt, BigFloat, BigFloat)
|
||||
DEFINE_MAX_TYPE(BigInt, BigRat, BigRat)
|
||||
DEFINE_MAX_TYPE(BigInt, Expr, Expr)
|
||||
CORE_DEFINE_MAX_TYPE(BigInt, BigFloat, BigFloat)
|
||||
CORE_DEFINE_MAX_TYPE(BigInt, BigRat, BigRat)
|
||||
CORE_DEFINE_MAX_TYPE(BigInt, Expr, Expr)
|
||||
|
||||
DEFINE_MAX_TYPE(BigFloat, BigRat, BigRat)
|
||||
DEFINE_MAX_TYPE(BigFloat, Expr, Expr)
|
||||
CORE_DEFINE_MAX_TYPE(BigFloat, BigRat, BigRat)
|
||||
CORE_DEFINE_MAX_TYPE(BigFloat, Expr, Expr)
|
||||
|
||||
DEFINE_MAX_TYPE(BigRat, Expr, Expr)
|
||||
CORE_DEFINE_MAX_TYPE(BigRat, Expr, Expr)
|
||||
|
||||
} //namespace CORE
|
||||
|
||||
#endif //__PROMOTE_H__
|
||||
#endif //_CORE_PROMOTE_H__
|
||||
|
|
|
|||
|
|
@ -277,12 +277,12 @@ 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) {
|
||||
if ((a > halfLongMax && b > halfLongMax) || (a < halfLongMin && b < halfLongMin))
|
||||
return BigInt(a)+BigInt(b);
|
||||
return BigInt(BigInt(a)+ BigInt(b));
|
||||
else
|
||||
return a+b;
|
||||
}
|
||||
|
|
@ -291,12 +291,12 @@ 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) {
|
||||
if ((a > halfLongMax && b < halfLongMin) || (a < halfLongMin && b > halfLongMax))
|
||||
return BigInt(a)-BigInt(b);
|
||||
return BigInt(BigInt(a)-BigInt(b));
|
||||
else
|
||||
return a-b;
|
||||
}
|
||||
|
|
@ -305,12 +305,12 @@ 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) {
|
||||
if (flrLg(a) + flrLg(b) >= static_cast<int>(LONG_BIT-2))
|
||||
return BigInt(a)*BigInt(b);
|
||||
return BigInt(BigInt(a)*BigInt(b));
|
||||
else
|
||||
return a*b;
|
||||
}
|
||||
|
|
@ -357,7 +357,7 @@ struct real_div {
|
|||
bf_a.approx(a.BigRatValue(), bf_b.MSB() - bf_b.flrLgErr() + 1, CORE_posInfty);
|
||||
return bf_a.div(bf_b, r);
|
||||
} else // both are BigRat
|
||||
return a.BigRatValue()/b.BigRatValue();
|
||||
return BigRat(a.BigRatValue() / b.BigRatValue());
|
||||
} else if (a.ID() == REAL_BIGFLOAT || b.ID() == REAL_BIGFLOAT
|
||||
|| a.ID() == REAL_DOUBLE || b.ID() == REAL_DOUBLE) {
|
||||
return a.BigFloatValue().div(b.BigFloatValue(), r);
|
||||
|
|
@ -478,11 +478,11 @@ inline Real sqrt(const Real& x) {
|
|||
// unary minus operator
|
||||
template <class T>
|
||||
inline Real Realbase_for<T>::operator-() const {
|
||||
return -ker;
|
||||
return T(- T(ker));
|
||||
}
|
||||
template <>
|
||||
inline Real RealLong::operator-() const {
|
||||
return ker < -LONG_MAX ? -BigInt(ker) : -ker;
|
||||
return ker < -LONG_MAX ? BigInt(- BigInt(ker)) : -ker;
|
||||
}
|
||||
|
||||
inline void init_CORE() {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include <CGAL/CORE/Impl.h>
|
||||
#include <CGAL/CORE/CoreAux.h>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
#ifndef LONG_MAX
|
||||
|
|
@ -77,6 +80,9 @@ public:
|
|||
extLong(long);
|
||||
/// constructor for \c unsigned long
|
||||
extLong(unsigned long);
|
||||
/// constructor for \c std::size_t
|
||||
template<typename T, typename = std::enable_if_t<std::is_same_v<T,std::size_t> && !std::is_same_v<unsigned long, std::size_t>>>
|
||||
extLong(T s);
|
||||
//@}
|
||||
|
||||
/// \name Arithmetic and assignment operators
|
||||
|
|
@ -149,8 +155,7 @@ const extLong EXTLONG_EIGHT(8);
|
|||
// private comparison function
|
||||
inline int extLong::cmp(const extLong& x) const {
|
||||
if (isNaN() || x.isNaN()) {
|
||||
core_error("Two extLong NaN's cannot be compared!",
|
||||
__FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, "Two extLong NaN's cannot be compared!");
|
||||
}
|
||||
return (val == x.val) ? 0 : ((val > x.val) ? 1 : -1);
|
||||
}
|
||||
|
|
@ -189,6 +194,17 @@ inline extLong::extLong(unsigned long u) {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T, typename>
|
||||
inline extLong::extLong(T u) {
|
||||
if (u >= (std::numeric_limits<std::size_t>::max)()) {
|
||||
val = EXTLONG_MAX;
|
||||
flag = 1;
|
||||
} else {
|
||||
val = static_cast<long>(u);
|
||||
flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// isNaN defaults to false
|
||||
inline extLong::extLong(bool isNaN) : val(0), flag(0) {
|
||||
if (isNaN) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ 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);
|
||||
CGAL_CORE_warning_msg(false, "extLong NaN Error in addition.");
|
||||
#endif
|
||||
|
||||
*this = CORE_NaNLong;
|
||||
|
|
@ -96,7 +96,7 @@ 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);
|
||||
CGAL_CORE_warning_msg(false, "extLong NaN Error in subtraction.");
|
||||
#endif
|
||||
|
||||
*this = CORE_NaNLong;
|
||||
|
|
@ -131,7 +131,7 @@ extLong& extLong::operator*= (const extLong& y) {
|
|||
*this = CORE_negInfty;
|
||||
} else {
|
||||
#ifdef CORE_DEBUG
|
||||
core_error("extLong NaN Error in multiplication.",__FILE__,__LINE__,false);
|
||||
CGAL_CORE_warning_msg(false, "extLong NaN Error in multiplication.");
|
||||
#endif
|
||||
*this = CORE_NaNLong;
|
||||
}
|
||||
|
|
@ -144,9 +144,9 @@ 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);
|
||||
CGAL_CORE_warning_msg(false, "extLong NaN Error, Divide by Zero.");
|
||||
else if ((flag !=0) && (y.flag !=0))
|
||||
core_error("extLong NaN Error, +/-Inf/Inf.", __FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, "extLong NaN Error, +/-Inf/Inf.");
|
||||
#endif
|
||||
|
||||
*this = CORE_NaNLong;
|
||||
|
|
@ -180,8 +180,7 @@ extLong extLong::operator- () const {
|
|||
// you cannot interpret the returned value!
|
||||
CGAL_INLINE_FUNCTION
|
||||
int extLong::sign() const {
|
||||
if (flag == 2)
|
||||
core_error("NaN Sign can not be determined!", __FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(flag != 2, "NaN Sign can not be determined!");
|
||||
return ((val == 0) ? 0 : ((val > 0) ? 1 : -1));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1336,7 +1336,7 @@ cout <<"Number of roots at " << xCurr << " are " << numRoots<<endl;
|
|||
if (!xCurr.isExact()){
|
||||
std::ostringstream oss;
|
||||
oss << "xCurr has error! xCurr=" << xCurr;
|
||||
core_error(oss.str(), __FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, oss.str());
|
||||
}
|
||||
}//main while loop
|
||||
|
||||
|
|
@ -1426,4 +1426,3 @@ void showIntervals(char* s, BFVecInterval &vI) {
|
|||
/*************************************************************************** */
|
||||
// END
|
||||
/*************************************************************************** */
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#define CORE_POLY_H
|
||||
|
||||
#include <CGAL/CORE/BigFloat.h>
|
||||
#include <CGAL/CORE/BigRat.h>
|
||||
#include <CGAL/CORE/Promote.h>
|
||||
#include <vector>
|
||||
#include <CGAL/assertions.h>
|
||||
|
|
@ -196,12 +197,10 @@ public:
|
|||
/// In particular, if the value is 0, we return 0.
|
||||
/// @param oldMSB is any estimate of the negative log of the evaluation
|
||||
BigFloat evalExactSign(const BigFloat& val, const extLong& oldMSB=54) const;
|
||||
|
||||
/// Polynomial evaluation that return the same type as its argument
|
||||
/// Caution: The type T must be greater or equal to the type NT
|
||||
/// NOTE: Eventually, we will remove this restriction by
|
||||
/// introduce MaxType(NT,T) for the return type.
|
||||
template <class T>
|
||||
MAX_TYPE(NT, T) eval(const T&) const;
|
||||
CORE_MAX_TYPE(NT, T) eval(const T&) const;
|
||||
|
||||
// Bounds
|
||||
BigFloat CauchyUpperBound() const; // Cauchy Root Upper Bound
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ Polynomial<NT> Polynomial<NT>::pseudoRemainder (
|
|||
int bTrueDegree = tmpB.degree;
|
||||
C = NT(1); // Initialized to C=1.
|
||||
if (bTrueDegree == -1) {
|
||||
core_error("ERROR in Polynomial<NT>::pseudoRemainder :\n -- divide by zero polynomial", __FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, "ERROR in Polynomial<NT>::pseudoRemainder :\n -- divide by zero polynomial");
|
||||
return Polynomial(0); // Unit Polynomial (arbitrary!)
|
||||
}
|
||||
if (bTrueDegree > degree) {
|
||||
|
|
@ -771,8 +771,8 @@ BigFloat Polynomial<NT>::eval(const BigFloat& f) const { // evaluation
|
|||
|
||||
template <class NT>
|
||||
template <class T>
|
||||
MAX_TYPE(NT, T) Polynomial<NT>::eval(const T& f) const { // evaluation
|
||||
typedef MAX_TYPE(NT, T) ResultT;
|
||||
CORE_MAX_TYPE(NT, T) Polynomial<NT>::eval(const T& f) const { // evaluation
|
||||
typedef CORE_MAX_TYPE(NT, T) ResultT;
|
||||
if (degree == -1)
|
||||
return ResultT(0);
|
||||
if (degree == 0)
|
||||
|
|
@ -892,10 +892,10 @@ BigFloat Polynomial<NT>::CauchyUpperBound() const {
|
|||
NT mx = 0;
|
||||
int deg = getTrueDegree();
|
||||
for (int i = 0; i < deg; ++i) {
|
||||
mx = core_max(mx, abs(coeff[i]));
|
||||
mx = core_max(mx, NT(abs(coeff[i])));
|
||||
}
|
||||
Expr e = mx;
|
||||
e /= Expr(abs(coeff[deg]));
|
||||
e /= Expr(NT(abs(coeff[deg])));
|
||||
e.approx(CORE_INFTY, 2);
|
||||
// get an absolute approximate value with error < 1/4
|
||||
return (e.BigFloatValue().makeExact() + 2);
|
||||
|
|
@ -922,7 +922,7 @@ BigInt Polynomial<NT>::CauchyBound() const {
|
|||
/* compute B^{deg} */
|
||||
if (rhs <= lhs) {
|
||||
B <<= 1;
|
||||
rhs *= (BigInt(1)<<deg);
|
||||
rhs *= BigFloat(BigInt(BigInt(1)<<deg));
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
|
@ -959,7 +959,7 @@ BigInt Polynomial<NT>::UpperBound() const {
|
|||
/* compute B^{deg} */
|
||||
if (rhs <= (std::max)(lhsPos,lhsNeg)) {
|
||||
B <<= 1;
|
||||
rhs *= (BigInt(1)<<deg);
|
||||
rhs *= BigFloat(BigInt(BigInt(1)<<deg));
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
|
@ -975,9 +975,9 @@ BigFloat Polynomial<NT>::CauchyLowerBound() const {
|
|||
NT mx = 0;
|
||||
int deg = getTrueDegree();
|
||||
for (int i = 1; i <= deg; ++i) {
|
||||
mx = core_max(mx, abs(coeff[i]));
|
||||
mx = core_max(mx, NT(abs(coeff[i])));
|
||||
}
|
||||
Expr e = Expr(abs(coeff[0]))/ Expr(abs(coeff[0]) + mx);
|
||||
Expr e = Expr(NT(abs(coeff[0])))/ Expr(NT(NT(abs(coeff[0])) + mx));
|
||||
e.approx(2, CORE_INFTY);
|
||||
// get an relative approximate value with error < 1/4
|
||||
return (e.BigFloatValue().makeExact().div2());
|
||||
|
|
@ -1018,8 +1018,8 @@ BigFloat Polynomial<NT>::height() const {
|
|||
int deg = getTrueDegree();
|
||||
NT ht = 0;
|
||||
for (int i = 0; i< deg; i++)
|
||||
if (ht < abs(coeff[i]))
|
||||
ht = abs(coeff[i]);
|
||||
if (ht < NT(abs(coeff[i])))
|
||||
ht = NT(abs(coeff[i]));
|
||||
return BigFloat(ht);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -607,8 +607,7 @@ public:
|
|||
if (ff == 0) {
|
||||
NEWTON_DIV_BY_ZERO = true;
|
||||
del = 0;
|
||||
core_error("Zero divisor in Newton Iteration",
|
||||
__FILE__, __LINE__, false);
|
||||
CGAL_CORE_warning_msg(false, "Zero divisor in Newton Iteration");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -680,8 +679,7 @@ public:
|
|||
stepsize++; // heuristic
|
||||
} while ((del != 0) && ((del.uMSB() >= -prec) && (count >0))) ;
|
||||
|
||||
if (count == 0) core_error("newtonIterE: reached count=0",
|
||||
__FILE__, __LINE__, true);
|
||||
CGAL_assertion_msg(count != 0, "newtonIterE: reached count=0");
|
||||
del = BigFloat(core_abs(del.m()), err, del.exp() );
|
||||
del.makeCeilExact();
|
||||
return val;
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
LGPL (v3)
|
||||
LGPL (v3 or later)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Algebraic_kernel_for_circles
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circular_kernel_2
|
||||
Distance_2
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Algebraic_kernel_for_spheres
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circular_kernel_3
|
||||
Distance_2
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Combinatorial_map
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
Arithmetic_kernel
|
||||
BGL
|
||||
Box_intersection_d
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Convex_decomposition_3
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Convex_hull_2
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ or <A HREF="https://msdn.microsoft.com/en-us/library/1fe2x6kt(v=vs.140).aspx">`h
|
|||
The \stl comes with the compiler, and as such no installation is required.
|
||||
|
||||
\subsection thirdpartyBoost Boost
|
||||
<b>Version 1.66 or later</b>
|
||||
<b>Version 1.72 or later</b>
|
||||
|
||||
The \boost libraries are a set of portable C++ source libraries.
|
||||
Most of \boost libraries are header-only, but a few of them need to be compiled or
|
||||
|
|
@ -72,7 +72,7 @@ from <A HREF="https://sourceforge.net/projects/boost/files/boost-binaries/">`htt
|
|||
|
||||
As there is no canonical directory for where to find \boost on Windows,
|
||||
we recommend that you define the environment variable
|
||||
`BOOST_ROOT` and set it to where you have installed \boost, e.g., `C:\boost\boost_1_69_0`.
|
||||
`BOOST_ROOT` and set it to where you have installed \boost, e.g., `C:\boost\boost_1_70_0`.
|
||||
|
||||
\subsection thirdpartyMPFR GNU Multiple Precision Arithmetic (GMP) and GNU Multiple Precision Floating-Point Reliably (MPFR) Libraries
|
||||
<b>GMP Version 4.2 or later, MPFR Version 2.2.1 or later</b>
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ other but never both.
|
|||
|
||||
\subsection installation_boost Boost Libraries
|
||||
|
||||
\subsubsection inst_boost_1_70_plus Version 1.70 and Later
|
||||
Starting from \boost 1.70, the cmake config mode can be used for configuring the \boost version
|
||||
\subsubsection inst_boost_1_72_plus Version 1.72 and Later
|
||||
Starting from \boost 1.72, the cmake config mode can be used for configuring the \boost version
|
||||
to use by setting the environment variable `Boost_DIR` to the path containing the file
|
||||
`BoostConfig.cmake`. For example if you manually installed \boost 1.77 with `--prefix=<path>`,
|
||||
then you should set `Boost_DIR=<path>/lib/cmake/Boost-1.77.0`.
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ public:
|
|||
if (n_ys == 0) return o; // no intersection
|
||||
|
||||
// the x coordinate of the solution points
|
||||
Algebraic xs = m / (2*a_diff);
|
||||
Algebraic xs = m / (Rational(2)*a_diff);
|
||||
|
||||
if (n_ys == 1) {
|
||||
// intersection is a point
|
||||
|
|
@ -340,7 +340,7 @@ public:
|
|||
}
|
||||
if (n_xs == 1) {
|
||||
// intersection is a point
|
||||
Point_2 inter_point(xs[0], (-2*a_diff*xs[0] + m)/(2*b_diff) );
|
||||
Point_2 inter_point(xs[0], (-Rational(2)*a_diff*xs[0] + m)/(Rational(2)*b_diff) );
|
||||
*o++ = inter_point;
|
||||
return o;
|
||||
}
|
||||
|
|
@ -350,8 +350,8 @@ public:
|
|||
// so we construct a COLLINEAR conic (with equation as in (1))
|
||||
// with 2 endpoints
|
||||
Algebraic ys[2];
|
||||
ys[0] = (-2*a_diff*xs[0] + m)/(2*b_diff);
|
||||
ys[1] = (-2*a_diff*xs[1] + m)/(2*b_diff);
|
||||
ys[0] = (-Rational(2)*a_diff*xs[0] + m)/(Rational(2)*b_diff);
|
||||
ys[1] = (-Rational(2)*a_diff*xs[1] + m)/(Rational(2)*b_diff);
|
||||
|
||||
Alg_point_2 end1(xs[0], ys[0]);
|
||||
Alg_point_2 end2(xs[1], ys[1]);
|
||||
|
|
@ -457,7 +457,7 @@ public:
|
|||
int envelope_coef = 1;
|
||||
if (! m_traits.m_is_lower) envelope_coef = -1;
|
||||
|
||||
Sign sign_c_diff = CGAL_NTS sign(c_diff);
|
||||
Rational sign_c_diff = Rational(sign(c_diff));
|
||||
Rational la = envelope_coef*2*a_diff*sign_c_diff;
|
||||
Rational lb = envelope_coef*2*b_diff*sign_c_diff;
|
||||
Rational lc = envelope_coef*sign_c_diff*(2*c_diff*z_plane - m);
|
||||
|
|
@ -977,10 +977,10 @@ public:
|
|||
const Rational& u = cv.u();
|
||||
const Rational& v = cv.v();
|
||||
// const Rational& w = cv.w(); // unused
|
||||
Algebraic m = -1 * (2*r*x0 + t*y0 + u);
|
||||
Algebraic n = 2*s*y0 + t*x0 + v;
|
||||
Algebraic m = -1 * (Rational(2)*r*x0 + t*y0 + u);
|
||||
Algebraic n = Rational(2)*s*y0 + t*x0 + v;
|
||||
// line coefficients: A3, B3, C3
|
||||
Algebraic A3 = -1*m, B3 = n, C3 = m*x0 - n*y0;
|
||||
Algebraic A3 = -m, B3 = n, C3 = m*x0 - n*y0;
|
||||
|
||||
// the tangences of the spheres (in point (x0,y0,z0)):
|
||||
Algebraic z0 = compute_envelope_z_in_point(cv_point, s1);
|
||||
|
|
@ -1077,8 +1077,8 @@ public:
|
|||
Algebraic x_diff = x1 - a, y_diff = y1 - b;
|
||||
// the coefficients are:
|
||||
Algebraic A = 1;
|
||||
Algebraic B = -2*c;
|
||||
Algebraic C = x_diff*x_diff + y_diff*y_diff + c*c - sqr_r;
|
||||
Algebraic B = -Rational(2)*c;
|
||||
Algebraic C = x_diff*x_diff + y_diff*y_diff + Algebraic(c*c - sqr_r);
|
||||
|
||||
Algebraic zs[2];
|
||||
Algebraic* zs_end;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
Apollonius_graph_2
|
||||
Arithmetic_kernel
|
||||
Arrangement_on_surface_2
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Distance_2
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Distance_2
|
||||
Distance_3
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Combinatorial_map
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ Release date: October 2023
|
|||
- **Breaking change**: The usage of `boost::optional` has been replaced by `std::optional`. Packages affected are 2D Straight Line Skeleton, 3D Fast Intersection and Distance Computation (AABB Tree), and the Kernel intersection.
|
||||
- **Breaking change**: The usage of `boost::variant` has been replaced by `std::variant`. Packages affected are 2D Arrangements, and the Kernel intersection.
|
||||
- **Breaking change**: The file CMake file `UseCGAL.cmake` has been removed from CGAL. Usages of the CMake variables `${CGAL_USE_FILE}` and `${CGAL_LIBRARIES}` must be replaced by a link to the imported target `CGAL::CGAL`, for example: `target_link_library(the_target PRIVATE CGAL::CGAL)`.
|
||||
- The minimal supported version of Boost is now 1.72.0
|
||||
|
||||
### Installation
|
||||
|
||||
- The CGAL\_Core library is no longer based on GMP but boost multiprecision now, and can be used with either gmp backend or boost backend.
|
||||
|
||||
### [Polygon Repair](https://doc.cgal.org/6.0/Manual/packages.html#PkgPolygonRepair) (new package)
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,9 @@ option(CGAL_ENABLE_TESTING "Build the testing tree." ${BUILD_TESTING})
|
|||
endif()
|
||||
endif(CGAL_BRANCH_BUILD)
|
||||
|
||||
#allow to force disabling boost multiprecision support
|
||||
option(CGAL_DO_NOT_USE_BOOST_MP "Disable the support of boost multiprecision library" FALSE)
|
||||
|
||||
#message(STATUS "Packages found: ${CGAL_CONFIGURED_PACKAGES}")
|
||||
|
||||
list(SORT CGAL_CONFIGURED_PACKAGES_NAMES)
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ set ( CGAL_Boost_Setup TRUE )
|
|||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake)
|
||||
|
||||
find_package( Boost 1.66 REQUIRED )
|
||||
find_package( Boost 1.72 REQUIRED )
|
||||
|
||||
if(Boost_FOUND AND Boost_VERSION VERSION_LESS 1.70)
|
||||
if(Boost_FOUND AND Boost_VERSION VERSION_LESS 1.72)
|
||||
if(DEFINED Boost_DIR AND NOT Boost_DIR)
|
||||
# Unset that cache variable that is set in the cache by FindBoost
|
||||
# (while it was searching for boost-cmake).
|
||||
|
|
|
|||
|
|
@ -131,12 +131,6 @@ function(CGAL_setup_CGAL_flags target)
|
|||
$<$<COMPILE_LANGUAGE:CXX>:/fp:except->
|
||||
$<$<COMPILE_LANGUAGE:CXX>:/bigobj> # Use /bigobj by default
|
||||
)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0.3)
|
||||
message(STATUS "Apple Clang version ${CMAKE_CXX_COMPILER_VERSION} compiler detected")
|
||||
message(STATUS "Boost MP is turned off for all Apple Clang versions below 11.0.3!")
|
||||
target_compile_options(${target} INTERFACE "-DCGAL_DO_NOT_USE_BOOST_MP")
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||
message( STATUS "Using Intel Compiler. Adding -fp-model strict" )
|
||||
if(WIN32)
|
||||
|
|
@ -166,4 +160,9 @@ function(CGAL_setup_CGAL_flags target)
|
|||
target_compile_options(${target} INTERFACE "-mieee" "-mfp-rounding-mode=d" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CGAL_DO_NOT_USE_BOOST_MP)
|
||||
target_compile_options(${target} INTERFACE "-DCGAL_DO_NOT_USE_BOOST_MP")
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ endif()
|
|||
set(CGAL_SetupCGAL_CoreDependencies_included TRUE)
|
||||
|
||||
#.rst:
|
||||
# Used Modules
|
||||
# ^^^^^^^^^^^^
|
||||
# - :module:`CGAL_SetupGMP`
|
||||
#
|
||||
# Result Variables
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
|
|
@ -29,13 +26,10 @@ set(CGAL_SetupCGAL_CoreDependencies_included TRUE)
|
|||
#
|
||||
# Set to `TRUE` if the dependencies of `CGAL_Core` were found.
|
||||
|
||||
if(NOT CGAL_DISABLE_GMP)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/CGAL_SetupGMP.cmake)
|
||||
if(GMP_FOUND)
|
||||
set(CGAL_Core_FOUND TRUE)
|
||||
set_property(GLOBAL PROPERTY CGAL_Core_FOUND TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# always found as it requires the minimal version of boost required by CGAL
|
||||
set(CGAL_Core_FOUND TRUE)
|
||||
set_property(GLOBAL PROPERTY CGAL_Core_FOUND TRUE)
|
||||
|
||||
#.rst:
|
||||
#
|
||||
|
|
@ -54,8 +48,10 @@ endif()
|
|||
#
|
||||
|
||||
function(CGAL_setup_CGAL_Core_dependencies target)
|
||||
use_CGAL_GMP_support(CGAL_Core INTERFACE)
|
||||
find_package( Boost 1.72 REQUIRED )
|
||||
if (!CGAL_DISABLE_GMP AND GMP_FOUND)
|
||||
use_CGAL_GMP_support(CGAL_Core INTERFACE)
|
||||
endif()
|
||||
target_compile_definitions(${target} INTERFACE CGAL_USE_CORE=1)
|
||||
target_link_libraries( CGAL_Core INTERFACE CGAL::CGAL )
|
||||
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
include(${CMAKE_CURRENT_LIST_DIR}/CGAL_Macros.cmake)
|
||||
|
||||
if( (GMP_FOUND AND NOT MPFR_FOUND) OR (NOT GMP_FOUND AND MPFR_FOUND) )
|
||||
message( FATAL_ERROR "CGAL needs for its full functionality both GMP and MPFR.")
|
||||
endif()
|
||||
|
||||
if( NOT GMP_FOUND )
|
||||
set(CGAL_NO_CORE ON)
|
||||
message( STATUS "CGAL_Core needs GMP, cannot be configured.")
|
||||
endif( NOT GMP_FOUND )
|
||||
|
||||
# finally setup Boost
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/CGAL_SetupBoost.cmake)
|
||||
|
|
@ -35,8 +35,32 @@
|
|||
# endif // CGAL_USE_MPFR and no <mpfr.h>
|
||||
#endif // __has_include
|
||||
|
||||
#if CGAL_USE_GMP && CGAL_USE_MPFR && ! CGAL_NO_CORE
|
||||
|
||||
// It is easier to disable this number type completely for old versions.
|
||||
// Before 1.63, I/O is broken. Again, disabling the whole file is just the
|
||||
// easy solution.
|
||||
// MSVC had trouble with versions <= 1.69:
|
||||
// https://github.com/boostorg/multiprecision/issues/98
|
||||
//
|
||||
// Disable also on Windows 32 bits
|
||||
// because CGAL/cpp_float.h assumes _BitScanForward64 is available
|
||||
// See https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64
|
||||
//
|
||||
// Disable also with PowerPC processors, with Boost<1.80 because of that bug:
|
||||
// https://github.com/boostorg/multiprecision/pull/421
|
||||
//
|
||||
#if !defined CGAL_DO_NOT_USE_BOOST_MP && \
|
||||
(!defined _MSC_VER || BOOST_VERSION >= 107000) && \
|
||||
(!defined _WIN32 || defined _WIN64) && \
|
||||
(BOOST_VERSION >= 108000 || (!defined _ARCH_PPC && !defined _ARCH_PPC64))
|
||||
#define CGAL_USE_BOOST_MP 1
|
||||
#endif
|
||||
|
||||
|
||||
#if CGAL_USE_BOOST_MP
|
||||
#if ! CGAL_NO_CORE
|
||||
# define CGAL_USE_CORE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // CGAL_INTERNAL_ENABLE_THIRD_PARTY_LIBRARIES_H
|
||||
|
|
|
|||
|
|
@ -127,12 +127,18 @@ if( CGAL_DEV_MODE OR RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE )
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0.3)
|
||||
message(STATUS "Apple Clang version ${CMAKE_CXX_COMPILER_VERSION} compiler detected")
|
||||
message(STATUS "Boost MP is turned off for all Apple Clang versions below 11.0.3!")
|
||||
set(CGAL_DO_NOT_USE_BOOST_MP TRUE)
|
||||
endif()
|
||||
|
||||
foreach(comp ${CGAL_FIND_COMPONENTS})
|
||||
if(NOT comp MATCHES "Core|ImageIO|Qt6")
|
||||
message(FATAL_ERROR "The requested CGAL component ${comp} does not exist!")
|
||||
endif()
|
||||
if(comp MATCHES "Core" AND CGAL_DISABLE_GMP)
|
||||
message("CGAL_Core needs GMP and won't be used.")
|
||||
if(comp MATCHES "Core" AND CGAL_DO_NOT_USE_BOOST_MP)
|
||||
message(STATUS "CGAL_Core needs Boost multiprecision support and won't be used.")
|
||||
else()
|
||||
list(APPEND CGAL_LIBRARIES CGAL_${comp})
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,165 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Combinatorial_map
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ AABB_tree
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
CGAL_Core
|
||||
CGAL_ImageIO
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ Algebraic_foundations
|
|||
Arithmetic_kernel
|
||||
Arrangement_on_surface_2
|
||||
Boolean_set_operations_2
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Convex_hull_2
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
Arithmetic_kernel
|
||||
BGL
|
||||
Box_intersection_d
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Convex_decomposition_3
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
Arithmetic_kernel
|
||||
BGL
|
||||
Box_intersection_d
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Distance_2
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Filtered_kernel
|
||||
Installation
|
||||
Interval_support
|
||||
|
|
|
|||
|
|
@ -178,13 +178,16 @@ public:
|
|||
|
||||
// shift such that err.m()+err.err() fits into long
|
||||
int digits_long = std::numeric_limits<long>::digits;
|
||||
if(::CORE::bitLength(err.m()+err.err()) >= digits_long){
|
||||
long shift = ::CORE::bitLength(err.m()) - digits_long + 1 ;
|
||||
if(::CORE::bitLength(err.m()+err.err()) >= static_cast<std::size_t>(digits_long)){
|
||||
assert(std::size_t((std::numeric_limits<long>::max)()) > ::CORE::bitLength(err.m()));
|
||||
long shift = static_cast<long>(::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");
|
||||
|
||||
|
|
@ -272,9 +275,10 @@ round(const CORE::BigFloat& x, long rel_prec = CORE::get_static_defRelPrec().toL
|
|||
// long shift = ::CORE::bitLength(m) - rel_prec - 1;
|
||||
|
||||
long shift ;
|
||||
if (err == 0)
|
||||
shift = ::CORE::bitLength(m) - rel_prec - 3;
|
||||
else
|
||||
if (err == 0) {
|
||||
assert(std::size_t((std::numeric_limits<long>::max)()) > ::CORE::bitLength(m));
|
||||
shift = static_cast<long>(::CORE::bitLength(m)) - rel_prec - 3;
|
||||
}else
|
||||
shift = CGAL::relative_precision(x) - rel_prec -1;
|
||||
|
||||
if( shift > 0 ){
|
||||
|
|
@ -324,7 +328,7 @@ public:
|
|||
NT w = Width()(x);
|
||||
w /= ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
|
||||
w = w.abs();
|
||||
return -(CORE::ceilLg(w.m()+w.err())+w.exp()*CORE::CHUNK_BIT);
|
||||
return -(CORE::ceilLg(CORE::BigInt(w.m()+w.err()))+w.exp()*CORE::CHUNK_BIT);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
//
|
||||
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
|
||||
|
||||
|
||||
#ifndef CGAL_CORE_BIGINT_H
|
||||
#define CGAL_CORE_BIGINT_H
|
||||
|
||||
|
|
@ -24,198 +23,6 @@
|
|||
#include <CGAL/Residue.h>
|
||||
#include <CGAL/Modular_traits.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
//
|
||||
// Algebraic structure traits
|
||||
//
|
||||
template <> class Algebraic_structure_traits< CORE::BigInt >
|
||||
: public Algebraic_structure_traits_base< CORE::BigInt,
|
||||
Euclidean_ring_tag > {
|
||||
public:
|
||||
typedef Tag_true Is_exact;
|
||||
typedef Tag_false Is_numerical_sensitive;
|
||||
|
||||
typedef INTERN_AST::Is_square_per_sqrt< Type >
|
||||
Is_square;
|
||||
|
||||
typedef INTERN_AST::Div_per_operator< Type > Div;
|
||||
typedef INTERN_AST::Mod_per_operator< Type > Mod;
|
||||
|
||||
class Sqrt
|
||||
: public CGAL::cpp98::unary_function< Type, Type > {
|
||||
public:
|
||||
//! computes the largest NT not larger than the square root of \a a.
|
||||
Type operator()( const Type& x) const {
|
||||
Type result;
|
||||
mpz_sqrt(result.get_mp(), x.get_mp());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Gcd
|
||||
: public CGAL::cpp98::binary_function< Type, Type,
|
||||
Type > {
|
||||
public:
|
||||
Type operator()( const Type& x,
|
||||
const Type& y) const {
|
||||
if ( x == Type(0) && y == Type(0) )
|
||||
return Type(0);
|
||||
Type result;
|
||||
mpz_gcd(result.get_mp(), x.get_mp(), y.get_mp());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// Real embeddable traits
|
||||
//
|
||||
template <> class Real_embeddable_traits< CORE::BigInt >
|
||||
: public INTERN_RET::Real_embeddable_traits_base< CORE::BigInt , CGAL::Tag_true > {
|
||||
|
||||
public:
|
||||
|
||||
class Abs
|
||||
: public CGAL::cpp98::unary_function< Type, Type > {
|
||||
public:
|
||||
Type operator()( const Type& x ) const {
|
||||
return CORE::abs( x );
|
||||
}
|
||||
};
|
||||
|
||||
class Sgn
|
||||
: public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > {
|
||||
public:
|
||||
::CGAL::Sign operator()( const Type& x ) const {
|
||||
return (::CGAL::Sign) CORE::sign( x );
|
||||
}
|
||||
};
|
||||
|
||||
class Compare
|
||||
: public CGAL::cpp98::binary_function< Type, Type,
|
||||
Comparison_result > {
|
||||
public:
|
||||
Comparison_result operator()( const Type& x,
|
||||
const Type& y ) const {
|
||||
return CGAL::sign(::CORE::cmp(x,y));
|
||||
}
|
||||
};
|
||||
|
||||
class To_double
|
||||
: public CGAL::cpp98::unary_function< Type, double > {
|
||||
public:
|
||||
double operator()( const Type& x ) const {
|
||||
// this call is required to get reasonable values for the double
|
||||
// approximation
|
||||
return x.doubleValue();
|
||||
}
|
||||
};
|
||||
|
||||
class To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
public:
|
||||
std::pair<double, double> operator()( const Type& x_ ) const {
|
||||
CORE::Expr x(x_);
|
||||
std::pair<double,double> result;
|
||||
x.doubleInterval(result.first, result.second);
|
||||
CGAL_expensive_assertion(result.first <= x);
|
||||
CGAL_expensive_assertion(result.second >= x);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*! \ingroup NiX_Modular_traits_spec
|
||||
* \brief a model of concept ModularTraits,
|
||||
* specialization of NiX::Modular_traits.
|
||||
*/
|
||||
template<>
|
||||
class Modular_traits< ::CORE::BigInt > {
|
||||
typedef Residue RES;
|
||||
public:
|
||||
typedef ::CORE::BigInt NT;
|
||||
typedef CGAL::Tag_true Is_modularizable;
|
||||
typedef Residue Residue_type;
|
||||
|
||||
struct Modular_image{
|
||||
Residue_type operator()(const NT& a){
|
||||
NT tmp = a % NT(RES::get_current_prime());
|
||||
// TODO: reactivate this assertion
|
||||
// it fails with core_v1.6x_20040329
|
||||
// NiX_assert(tmp.isInt());
|
||||
int mi(tmp.longValue());
|
||||
if (mi < 0) mi += RES::get_current_prime();
|
||||
return Residue_type(mi);
|
||||
}
|
||||
};
|
||||
struct Modular_image_representative{
|
||||
NT operator()(const Residue_type& x){
|
||||
return NT(x.get_value());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct Needs_parens_as_product<CORE::BigInt>{
|
||||
bool operator()(const CORE::BigInt& x){
|
||||
return CGAL_NTS is_negative(x);
|
||||
}
|
||||
};
|
||||
|
||||
// Benchmark_rep specialization
|
||||
template<>
|
||||
class Benchmark_rep< CORE::BigInt > {
|
||||
const CORE::BigInt& t;
|
||||
public:
|
||||
//! initialize with a const reference to \a t.
|
||||
Benchmark_rep( const CORE::BigInt& tt) : t(tt) {}
|
||||
//! perform the output, calls \c operator\<\< by default.
|
||||
std::ostream& operator()( std::ostream& out) const {
|
||||
out << t;
|
||||
return out;
|
||||
}
|
||||
|
||||
static std::string get_benchmark_name() {
|
||||
return "Integer";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
//since types are included by CORE_coercion_traits.h:
|
||||
#include <CGAL/CORE_Expr.h>
|
||||
#include <CGAL/CORE_BigRat.h>
|
||||
#include <CGAL/CORE_BigFloat.h>
|
||||
#include <CGAL/CORE_arithmetic_kernel.h>
|
||||
|
||||
namespace Eigen {
|
||||
template<class> struct NumTraits;
|
||||
template<> struct NumTraits<CORE::BigInt>
|
||||
{
|
||||
typedef CORE::BigInt Real;
|
||||
typedef CORE::BigRat NonInteger;
|
||||
typedef CORE::BigInt Nested;
|
||||
typedef CORE::BigInt Literal;
|
||||
|
||||
static inline Real epsilon() { return 0; }
|
||||
static inline Real dummy_precision() { return 0; }
|
||||
|
||||
enum {
|
||||
IsInteger = 1,
|
||||
IsSigned = 1,
|
||||
IsComplex = 0,
|
||||
RequireInitialization = 1,
|
||||
ReadCost = 6,
|
||||
AddCost = 30,
|
||||
MulCost = 50
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif // CGAL_CORE_BIGINT_H
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
//
|
||||
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
|
||||
|
||||
|
||||
#ifndef CGAL_CORE_BIGRAT_H
|
||||
#define CGAL_CORE_BIGRAT_H
|
||||
|
||||
|
|
@ -21,237 +20,6 @@
|
|||
#include <CGAL/CORE_coercion_traits.h>
|
||||
#include <CGAL/CORE_Expr.h> // used for To_interval-functor
|
||||
|
||||
//#if defined(CGAL_CORE_BIGRAT_NUMER_DENOM_ARE_MEMBERS)
|
||||
// #define CGAL_CORE_NUMERATOR(X) ((X).numerator())
|
||||
// #define CGAL_CORE_DENOMINATOR(X) ((X).denominator())
|
||||
//#elif defined(CGAL_CORE_BIGRAT_NUMER_DENOM_ARE_NONMEMBERS)
|
||||
#define CGAL_CORE_NUMERATOR(X) (numerator((X)))
|
||||
#define CGAL_CORE_DENOMINATOR(X) (denominator((X)))
|
||||
//#else
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
//
|
||||
// Algebraic structure traits
|
||||
//
|
||||
template <> class Algebraic_structure_traits< CORE::BigRat >
|
||||
: public Algebraic_structure_traits_base< CORE::BigRat,
|
||||
Field_tag > {
|
||||
public:
|
||||
typedef Tag_true Is_exact;
|
||||
typedef Tag_false Is_numerical_sensitive;
|
||||
|
||||
// BigRat are always normalized, so no special simplify-functor is needed
|
||||
|
||||
// Nothing new...
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Real embeddable traits
|
||||
//
|
||||
template <> class Real_embeddable_traits< CORE::BigRat >
|
||||
: public INTERN_RET::Real_embeddable_traits_base< CORE::BigRat , CGAL::Tag_true > {
|
||||
public:
|
||||
|
||||
class Abs
|
||||
: public CGAL::cpp98::unary_function< Type, Type > {
|
||||
public:
|
||||
Type operator()( const Type& x ) const {
|
||||
return CORE::abs( x );
|
||||
}
|
||||
};
|
||||
|
||||
class Sgn
|
||||
: public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > {
|
||||
public:
|
||||
::CGAL::Sign operator()( const Type& x ) const {
|
||||
return (::CGAL::Sign) CORE::sign( x );
|
||||
}
|
||||
};
|
||||
|
||||
class Compare
|
||||
: public CGAL::cpp98::binary_function< Type, Type,
|
||||
Comparison_result > {
|
||||
public:
|
||||
Comparison_result operator()( const Type& x,
|
||||
const Type& y ) const {
|
||||
return CGAL::sign( ::CORE::cmp(x,y));
|
||||
}
|
||||
CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT(Type,Comparison_result)
|
||||
};
|
||||
|
||||
class To_double
|
||||
: public CGAL::cpp98::unary_function< Type, double > {
|
||||
public:
|
||||
double operator()( const Type& x ) const {
|
||||
// this call is required to get reasonable values for the double
|
||||
// approximation
|
||||
return x.doubleValue();
|
||||
}
|
||||
};
|
||||
|
||||
class To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
public:
|
||||
std::pair<double, double> operator()( const Type& x_ ) const {
|
||||
CORE::Expr x(x_);
|
||||
std::pair<double,double> result;
|
||||
x.doubleInterval(result.first, result.second);
|
||||
CGAL_expensive_assertion(result.first <= x);
|
||||
CGAL_expensive_assertion(result.second >= x);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*! \ingroup NiX_Fraction_traits_spec
|
||||
* \brief Specialization of Fraction_traits for ::leda::rational
|
||||
*/
|
||||
template <>
|
||||
class Fraction_traits< CORE::BigRat > {
|
||||
public:
|
||||
typedef CORE::BigRat Type;
|
||||
typedef ::CGAL::Tag_true Is_fraction;
|
||||
typedef CORE::BigInt Numerator_type;
|
||||
typedef Numerator_type Denominator_type;
|
||||
|
||||
typedef Algebraic_structure_traits< Numerator_type >::Gcd Common_factor;
|
||||
|
||||
class Decompose {
|
||||
public:
|
||||
typedef Type first_argument_type;
|
||||
typedef Numerator_type& second_argument_type;
|
||||
typedef Numerator_type& third_argument_type;
|
||||
void operator () (
|
||||
const Type& rat,
|
||||
Numerator_type& num,
|
||||
Numerator_type& den) {
|
||||
num = CGAL_CORE_NUMERATOR(rat);
|
||||
den = CGAL_CORE_DENOMINATOR(rat);
|
||||
}
|
||||
};
|
||||
|
||||
class Compose {
|
||||
public:
|
||||
typedef Numerator_type first_argument_type;
|
||||
typedef Numerator_type second_argument_type;
|
||||
typedef Type result_type;
|
||||
Type operator ()(
|
||||
const Numerator_type& num ,
|
||||
const Numerator_type& den ) {
|
||||
return Type(num, den);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class F>
|
||||
class Output_rep< ::CORE::BigRat, F> : public IO_rep_is_specialized {
|
||||
const ::CORE::BigRat& t;
|
||||
public:
|
||||
//! initialize with a const reference to \a t.
|
||||
Output_rep( const ::CORE::BigRat& tt) : t(tt) {}
|
||||
//! perform the output, calls \c operator\<\< by default.
|
||||
std::ostream& operator()( std::ostream& out) const {
|
||||
switch (IO::get_mode(out)) {
|
||||
case IO::PRETTY:{
|
||||
if(CGAL_CORE_DENOMINATOR(t) == ::CORE::BigRat(1))
|
||||
return out <<CGAL_CORE_NUMERATOR(t);
|
||||
else
|
||||
return out << CGAL_CORE_NUMERATOR(t)
|
||||
<< "/"
|
||||
<< CGAL_CORE_DENOMINATOR(t);
|
||||
//break; // unreachable
|
||||
}
|
||||
|
||||
default:
|
||||
return out << CGAL_CORE_NUMERATOR(t)
|
||||
<< "/"
|
||||
<< CGAL_CORE_DENOMINATOR(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Needs_parens_as_product< ::CORE::BigRat >{
|
||||
bool operator()( ::CORE::BigRat t){
|
||||
if (CGAL_CORE_DENOMINATOR(t) != 1 )
|
||||
return true;
|
||||
else
|
||||
return needs_parens_as_product(CGAL_CORE_NUMERATOR(t)) ;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class Output_rep< ::CORE::BigRat, Parens_as_product_tag >
|
||||
: public IO_rep_is_specialized
|
||||
{
|
||||
const ::CORE::BigRat& t;
|
||||
public:
|
||||
// Constructor
|
||||
Output_rep( const ::CORE::BigRat& tt) : t(tt) {}
|
||||
// operator
|
||||
std::ostream& operator()( std::ostream& out) const {
|
||||
Needs_parens_as_product< ::CORE::BigRat > needs_parens_as_product;
|
||||
if (needs_parens_as_product(t))
|
||||
return out <<"("<< IO::oformat(t) <<")";
|
||||
else
|
||||
return out << IO::oformat(t);
|
||||
}
|
||||
};
|
||||
|
||||
// Benchmark_rep specialization
|
||||
template<>
|
||||
class Benchmark_rep< CORE::BigRat > {
|
||||
const CORE::BigRat& t;
|
||||
public:
|
||||
//! initialize with a const reference to \a t.
|
||||
Benchmark_rep( const CORE::BigRat& tt) : t(tt) {}
|
||||
//! perform the output, calls \c operator\<\< by default.
|
||||
std::ostream& operator()( std::ostream& out) const {
|
||||
out << "Rational(" << numerator(t) << "," << denominator(t) << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
static std::string get_benchmark_name() {
|
||||
return "Rational";
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
//since types are included by CORE_coercion_traits.h:
|
||||
#include <CGAL/CORE_Expr.h>
|
||||
#include <CGAL/CORE_BigInt.h>
|
||||
#include <CGAL/CORE_BigFloat.h>
|
||||
#include <CGAL/CORE_arithmetic_kernel.h>
|
||||
|
||||
namespace Eigen {
|
||||
template<class> struct NumTraits;
|
||||
template<> struct NumTraits<CORE::BigRat>
|
||||
{
|
||||
typedef CORE::BigRat Real;
|
||||
typedef CORE::BigRat NonInteger;
|
||||
typedef CORE::BigRat Nested;
|
||||
typedef CORE::BigRat Literal;
|
||||
|
||||
static inline Real epsilon() { return 0; }
|
||||
static inline Real dummy_precision() { return 0; }
|
||||
|
||||
enum {
|
||||
IsInteger = 0,
|
||||
IsSigned = 1,
|
||||
IsComplex = 0,
|
||||
RequireInitialization = 1,
|
||||
ReadCost = 6,
|
||||
AddCost = 150,
|
||||
MulCost = 100
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#include <CGAL/enable_warnings.h>
|
||||
|
||||
#endif // CGAL_CORE_BIGRAT_H
|
||||
|
|
|
|||
|
|
@ -24,29 +24,11 @@
|
|||
|
||||
#include <CGAL/CORE/CORE.h>
|
||||
|
||||
//#include <NiX/Coercion_traits.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
//CORE internal coercions:
|
||||
|
||||
|
||||
// The following definitions reflect the interaction of the CORE number types
|
||||
// with the built in types,
|
||||
// CORE BigInt:
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short ,::CORE::BigInt)
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int ,::CORE::BigInt)
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long ,::CORE::BigInt)
|
||||
|
||||
|
||||
// CORE BigRat:
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short ,::CORE::BigRat)
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int ,::CORE::BigRat)
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long ,::CORE::BigRat)
|
||||
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)
|
||||
|
||||
// CORE Expr:
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short ,::CORE::Expr)
|
||||
CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int ,::CORE::Expr)
|
||||
|
|
@ -75,12 +57,14 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigInt>{
|
|||
typedef Type result_type;
|
||||
Type operator()(const CORE::BigFloat& x) const { return x;}
|
||||
Type operator()(const ::CORE::BigInt x) const {
|
||||
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 );
|
||||
return result;
|
||||
CORE::BigFloat result;
|
||||
result.approx(x,CORE::get_static_defRelPrec().toLong(),LONG_MAX);
|
||||
// Do not use MakeFloorExact as it changes the Bigfloat
|
||||
CGAL_postcondition_code(::CORE::BigRat r = ::CORE::BigFloat(result.m()-result.err(),0,result.exp()));
|
||||
CGAL_postcondition( r <= x );
|
||||
CGAL_postcondition_code(::CORE::BigRat r2 = ::CORE::BigFloat(result.m()+result.err(),0,result.exp()));
|
||||
CGAL_postcondition( r2 >= x );
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -95,12 +79,13 @@ struct Coercion_traits<CORE::BigFloat , ::CORE::BigRat>{
|
|||
typedef Type result_type;
|
||||
Type operator()(const CORE::BigFloat& x) const { return x;}
|
||||
Type operator()(const ::CORE::BigRat 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 );
|
||||
return result;
|
||||
// Do not use MakeFloorExact as it changes the Bigfloat
|
||||
CGAL_postcondition_code(::CORE::BigRat r = ::CORE::BigFloat(result.m()-result.err(),0,result.exp()));
|
||||
CGAL_postcondition( r <= x );
|
||||
CGAL_postcondition_code(::CORE::BigRat r2 = ::CORE::BigFloat(result.m()+result.err(),0,result.exp()));
|
||||
CGAL_postcondition( r2 >= x );
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -115,11 +100,13 @@ 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::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 );
|
||||
return result;
|
||||
CORE::BigFloat result(x, CORE::get_static_defRelPrec().toLong(),LONG_MAX);
|
||||
// Do not use MakeFloorExact as it changes the Bigfloat
|
||||
CGAL_postcondition_code(::CORE::BigRat r = ::CORE::BigFloat(result.m()-result.err(),0,result.exp()));
|
||||
CGAL_postcondition( r <= x );
|
||||
CGAL_postcondition_code(::CORE::BigRat r2 = ::CORE::BigFloat(result.m()+result.err(),0,result.exp()));
|
||||
CGAL_postcondition( r2 >= x );
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -150,6 +137,8 @@ template <> struct Coercion_traits< ::CORE::Expr, CORE::BigFloat >
|
|||
|
||||
} //namespace CGAL
|
||||
|
||||
|
||||
|
||||
#endif // CGAL_USE_CORE
|
||||
#endif //CGAL_CORE_COERCION_TRAITS_H 1
|
||||
//EOF
|
||||
|
|
|
|||
|
|
@ -121,8 +121,12 @@ class Counted_number {
|
|||
Counted_number() {}
|
||||
//explicit Counted_number(int n) :m_rep(n){}
|
||||
explicit Counted_number(NT n) :m_rep(n){}
|
||||
|
||||
Counted_number operator-() const
|
||||
{inc_neg_count();return Counted_number(-m_rep);}
|
||||
{
|
||||
inc_neg_count(); NT neg = -m_rep; return Counted_number(neg);
|
||||
}
|
||||
|
||||
Counted_number const & operator+=(Counted_number const &n)
|
||||
{
|
||||
inc_add_count();
|
||||
|
|
@ -352,7 +356,7 @@ Counted_number<NT>
|
|||
operator+(Counted_number<NT> const &n1, Counted_number<NT> const &n2)
|
||||
{
|
||||
Counted_number<NT>::inc_add_count();
|
||||
return Counted_number<NT>(n1.rep() + n2.rep());
|
||||
return Counted_number<NT>(NT(n1.rep() + n2.rep()));
|
||||
}
|
||||
|
||||
template <class NT>
|
||||
|
|
@ -360,7 +364,7 @@ Counted_number<NT>
|
|||
operator-(Counted_number<NT> const &n1, Counted_number<NT> const &n2)
|
||||
{
|
||||
Counted_number<NT>::inc_sub_count();
|
||||
return Counted_number<NT>(n1.rep() - n2.rep());
|
||||
return Counted_number<NT>(NT(n1.rep() - n2.rep()));
|
||||
}
|
||||
|
||||
template <class NT>
|
||||
|
|
@ -368,7 +372,7 @@ Counted_number<NT>
|
|||
operator*(Counted_number<NT> const &n1, Counted_number<NT> const &n2)
|
||||
{
|
||||
Counted_number<NT>::inc_mul_count();
|
||||
return Counted_number<NT>(n1.rep() * n2.rep());
|
||||
return Counted_number<NT>(NT(n1.rep() * n2.rep()));
|
||||
}
|
||||
|
||||
template <class NT>
|
||||
|
|
@ -376,7 +380,7 @@ Counted_number<NT>
|
|||
operator/(Counted_number<NT> const &n1, Counted_number<NT> const &n2)
|
||||
{
|
||||
Counted_number<NT>::inc_div_count();
|
||||
return Counted_number<NT>(n1.rep() / n2.rep());
|
||||
return Counted_number<NT>(NT(n1.rep() / n2.rep()));
|
||||
}
|
||||
|
||||
template< class NT >
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@
|
|||
#include <CGAL/MP_Float.h>
|
||||
#include <CGAL/Quotient.h>
|
||||
|
||||
#include <CGAL/boost_mp.h>
|
||||
#ifdef CGAL_USE_BOOST_MP
|
||||
#include <CGAL/cpp_float.h>
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_USE_GMP
|
||||
# include <CGAL/Gmpz.h>
|
||||
|
|
|
|||
|
|
@ -76,7 +76,9 @@ compute_roots_of_2(const NT &a_, const NT &b_, const NT &c_, OutputIterator oit)
|
|||
}
|
||||
}
|
||||
else {
|
||||
*oit++ = -c/b; return oit;
|
||||
Root_of_1 cb = -c / b;
|
||||
*oit++ = Root_of_2(cb);
|
||||
return oit;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,902 +12,8 @@
|
|||
#ifndef CGAL_BOOST_MP_H
|
||||
#define CGAL_BOOST_MP_H
|
||||
|
||||
#include <CGAL/config.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
|
||||
// It is easier to disable this number type completely for old versions.
|
||||
// Before 1.63, I/O is broken. Again, disabling the whole file is just the
|
||||
// easy solution.
|
||||
// MSVC had trouble with versions <= 1.69:
|
||||
// https://github.com/boostorg/multiprecision/issues/98
|
||||
//
|
||||
// Disable also on Windows 32 bits
|
||||
// because CGAL/cpp_float.h assumes _BitScanForward64 is available
|
||||
// See https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64
|
||||
//
|
||||
// Disable also with PowerPC processors, with Boost<1.80 because of that bug:
|
||||
// https://github.com/boostorg/multiprecision/pull/421
|
||||
//
|
||||
#if !defined CGAL_DO_NOT_USE_BOOST_MP && \
|
||||
(!defined _MSC_VER || BOOST_VERSION >= 107000) && \
|
||||
(!defined _WIN32 || defined _WIN64) && \
|
||||
(BOOST_VERSION >= 108000 || (!defined _ARCH_PPC && !defined _ARCH_PPC64))
|
||||
#define CGAL_USE_BOOST_MP 1
|
||||
|
||||
#include <CGAL/Quotient.h>
|
||||
#include <CGAL/functional.h> // *ary_function
|
||||
#include <CGAL/number_type_basic.h>
|
||||
#include <CGAL/Modular_traits.h>
|
||||
// We can't just include all Boost.Multiprecision here...
|
||||
#include <boost/multiprecision/number.hpp>
|
||||
#include <boost/type_traits/common_type.hpp>
|
||||
// ... but we kind of have to :-(
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#ifdef CGAL_USE_GMP
|
||||
// Same dance as in CGAL/gmp.h
|
||||
# include <CGAL/disable_warnings.h>
|
||||
# if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127 4244 4146 4267) // conversion with loss of data
|
||||
// warning on - applied on unsigned number
|
||||
# endif
|
||||
|
||||
# include <boost/multiprecision/gmp.hpp>
|
||||
|
||||
# if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
# include <CGAL/enable_warnings.h>
|
||||
#endif
|
||||
#ifdef CGAL_USE_MPFR
|
||||
# include <mpfr.h>
|
||||
#endif
|
||||
|
||||
// TODO: work on the coercions (end of the file)
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// Algebraic_structure_traits
|
||||
|
||||
template <class T, class = boost::mpl::int_<boost::multiprecision::number_category<T>::value> >
|
||||
struct AST_boost_mp;
|
||||
|
||||
template <class NT>
|
||||
struct AST_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_integer> >
|
||||
: Algebraic_structure_traits_base< NT, Euclidean_ring_tag > {
|
||||
typedef NT Type;
|
||||
typedef Euclidean_ring_tag Algebraic_category;
|
||||
typedef Boolean_tag<std::numeric_limits<Type>::is_exact> Is_exact;
|
||||
typedef Tag_false Is_numerical_sensitive;
|
||||
|
||||
struct Is_zero: public CGAL::cpp98::unary_function<Type ,bool> {
|
||||
bool operator()( const Type& x) const {
|
||||
return x.is_zero();
|
||||
}
|
||||
};
|
||||
|
||||
struct Div:
|
||||
public CGAL::cpp98::binary_function<Type ,Type, Type> {
|
||||
template <typename T, typename U>
|
||||
Type operator()(const T& x, const U& y) const {
|
||||
return x / y;
|
||||
}
|
||||
};
|
||||
|
||||
struct Mod:
|
||||
public CGAL::cpp98::binary_function<Type ,Type, Type> {
|
||||
template <typename T, typename U>
|
||||
Type operator()(const T& x, const U& y) const {
|
||||
return x % y;
|
||||
}
|
||||
};
|
||||
|
||||
struct Gcd : public CGAL::cpp98::binary_function<Type, Type, Type> {
|
||||
template <typename T, typename U>
|
||||
Type operator()(const T& x, const U& y) const {
|
||||
return boost::multiprecision::gcd(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
struct Sqrt : public CGAL::cpp98::unary_function<Type, Type> {
|
||||
template <typename T>
|
||||
Type operator()(const T& x) const {
|
||||
return boost::multiprecision::sqrt(x);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class NT>
|
||||
struct AST_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_rational> >
|
||||
: public Algebraic_structure_traits_base< NT , Field_tag > {
|
||||
public:
|
||||
typedef NT Type;
|
||||
typedef Field_tag Algebraic_category;
|
||||
typedef Tag_true Is_exact;
|
||||
typedef Tag_false Is_numerical_sensitive;
|
||||
|
||||
struct Is_zero: public CGAL::cpp98::unary_function<Type ,bool> {
|
||||
bool operator()( const Type& x) const {
|
||||
return x.is_zero();
|
||||
}
|
||||
};
|
||||
|
||||
struct Div:
|
||||
public CGAL::cpp98::binary_function<Type ,Type, Type> {
|
||||
template <typename T, typename U>
|
||||
Type operator()(const T& x, const U& y) const {
|
||||
return x / y;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class Backend, boost::multiprecision::expression_template_option Eto>
|
||||
struct Algebraic_structure_traits<boost::multiprecision::number<Backend, Eto> >
|
||||
: AST_boost_mp <boost::multiprecision::number<Backend, Eto> > {};
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
struct Algebraic_structure_traits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> >
|
||||
: Algebraic_structure_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type > {};
|
||||
|
||||
// Real_embeddable_traits
|
||||
|
||||
namespace Boost_MP_internal {
|
||||
|
||||
// here we know that `intv` contains int64 numbers such that their msb is std::numeric_limits<double>::digits-1
|
||||
// TODO: possibly return denormals sometimes...
|
||||
inline
|
||||
std::pair<double,double> shift_positive_interval( const std::pair<double,double>& intv, const int e ) {
|
||||
CGAL_assertion(intv.first > 0.0);
|
||||
CGAL_assertion(intv.second > 0.0);
|
||||
|
||||
#ifdef CGAL_LITTLE_ENDIAN
|
||||
CGAL_assertion_code(
|
||||
union {
|
||||
struct { uint64_t man:52; uint64_t exp:11; uint64_t sig:1; } s;
|
||||
double d;
|
||||
} conv;
|
||||
|
||||
conv.d = intv.first;
|
||||
)
|
||||
#else
|
||||
//WARNING: untested!
|
||||
CGAL_assertion_code(
|
||||
union {
|
||||
|
||||
struct { uint64_t sig:1; uint64_t exp:11; uint64_t man:52; } s;
|
||||
double d;
|
||||
} conv;
|
||||
|
||||
conv.d = intv.first;
|
||||
)
|
||||
#endif
|
||||
// Check that the exponent of intv.inf is 52, which corresponds to a 53 bit integer
|
||||
CGAL_assertion(conv.s.exp - ((1 << (11 - 1)) - 1) == std::numeric_limits<double>::digits - 1);
|
||||
|
||||
typedef std::numeric_limits<double> limits;
|
||||
|
||||
// warning: min_exponent and max_exponent are 1 more than what the name suggests
|
||||
if (e < limits::min_exponent - limits::digits)
|
||||
return {0, (limits::min)()};
|
||||
if (e > limits::max_exponent - limits::digits)
|
||||
return {(limits::max)(), limits::infinity()}; // intv is positive
|
||||
|
||||
const double scale = std::ldexp(1.0, e); // ldexp call is exact
|
||||
return { scale * intv.first, scale * intv.second }; // cases that would require a rounding mode have been handled above
|
||||
}
|
||||
|
||||
// This function checks if the computed interval is correct and if it is tight.
|
||||
template<typename Type>
|
||||
bool are_bounds_correct( const double l, const double u, const Type& x ) {
|
||||
typedef std::numeric_limits<double> limits;
|
||||
|
||||
const double inf = std::numeric_limits<double>::infinity();
|
||||
if ( u!=l && (l==-inf || u==inf
|
||||
|| (u==0 && l >= -(limits::min)())
|
||||
|| (l==0 && u <= (limits::min)())) )
|
||||
{
|
||||
return x > Type((limits::max)()) ||
|
||||
x < Type(-(limits::max)()) ||
|
||||
(x > Type(-(limits::min)()) && x < Type((limits::min)()));
|
||||
}
|
||||
|
||||
if (!(u == l || u == std::nextafter(l, +inf))) return false;
|
||||
//TODO: Type(nextafter(l,inf))>x && Type(nextafter(u,-inf))<x
|
||||
|
||||
const Type lb(l), ub(u);
|
||||
const bool are_bounds_respected = (lb <= x && x <= ub);
|
||||
return are_bounds_respected;
|
||||
}
|
||||
|
||||
// This one returns zero length interval that is inf = sup.
|
||||
inline
|
||||
std::pair<double, double> get_0ulp_interval( const int shift, const uint64_t p ) {
|
||||
|
||||
const double pp_dbl = static_cast<double>(p);
|
||||
const std::pair<double,double> intv(pp_dbl, pp_dbl);
|
||||
|
||||
return shift_positive_interval(intv, -shift);
|
||||
}
|
||||
|
||||
// This one returns 1 unit length interval.
|
||||
inline
|
||||
std::pair<double, double> get_1ulp_interval( const int shift, const uint64_t p ) {
|
||||
|
||||
const double pp_dbl = static_cast<double>(p);
|
||||
const double qq_dbl = pp_dbl+1;
|
||||
const std::pair<double,double> intv(pp_dbl, qq_dbl);
|
||||
return shift_positive_interval(intv, -shift);
|
||||
}
|
||||
|
||||
template<typename ET>
|
||||
std::pair<double, double> to_interval( ET x, int extra_shift = 0 );
|
||||
|
||||
// This is a version of to_interval that converts a rational type into a
|
||||
// double tight interval.
|
||||
template<typename Type, typename ET>
|
||||
std::pair<double, double> to_interval( ET xnum, ET xden ) {
|
||||
|
||||
CGAL_assertion(!CGAL::is_zero(xden));
|
||||
CGAL_assertion_code(const Type input(xnum, xden));
|
||||
double l = 0.0, u = 0.0;
|
||||
if (CGAL::is_zero(xnum)) { // return [0.0, 0.0]
|
||||
CGAL_assertion(are_bounds_correct(l, u, input));
|
||||
return std::make_pair(l, u);
|
||||
}
|
||||
CGAL_assertion(!CGAL::is_zero(xnum));
|
||||
|
||||
// Handle signs.
|
||||
bool change_sign = false;
|
||||
const bool is_num_pos = CGAL::is_positive(xnum);
|
||||
const bool is_den_pos = CGAL::is_positive(xden);
|
||||
if (!is_num_pos && !is_den_pos) {
|
||||
xnum = -xnum;
|
||||
xden = -xden;
|
||||
} else if (!is_num_pos && is_den_pos) {
|
||||
change_sign = true;
|
||||
xnum = -xnum;
|
||||
} else if (is_num_pos && !is_den_pos) {
|
||||
change_sign = true;
|
||||
xden = -xden;
|
||||
}
|
||||
CGAL_assertion(CGAL::is_positive(xnum) && CGAL::is_positive(xden));
|
||||
|
||||
const int64_t num_dbl_digits = std::numeric_limits<double>::digits - 1;
|
||||
const int64_t msb_num = static_cast<int64_t>(boost::multiprecision::msb(xnum));
|
||||
const int64_t msb_den = static_cast<int64_t>(boost::multiprecision::msb(xden));
|
||||
|
||||
#if 0 // Optimisation for the case of input that are double
|
||||
// An alternative strategy would be to convert numerator and denominator to
|
||||
// intervals, then divide. However, this would require setting the rounding
|
||||
// mode (and dividing intervals is not completely free). An important
|
||||
// special case is when the rational is exactly equal to a double
|
||||
// (fit_in_double). Then the denominator is a power of 2, so we can skip
|
||||
// the division and it becomes unnecessary to set the rounding mode, we
|
||||
// just need to modify the exponent correction for the denominator.
|
||||
if(msb_den == static_cast<int64_t>(lsb(xden))) {
|
||||
std::tie(l,u)=to_interval(xnum, msb_den);
|
||||
if (change_sign) {
|
||||
CGAL_assertion(are_bounds_correct(-u, -l, input));
|
||||
return {-u, -l};
|
||||
}
|
||||
CGAL_assertion(are_bounds_correct(l, u, input));
|
||||
return {u, l};
|
||||
}
|
||||
#endif
|
||||
|
||||
const int64_t msb_diff = msb_num - msb_den;
|
||||
// Shift so the division result has at least 53 (and at most 54) bits
|
||||
int shift = static_cast<int>(num_dbl_digits - msb_diff + 1);
|
||||
CGAL_assertion(shift == num_dbl_digits - msb_diff + 1);
|
||||
|
||||
if (shift > 0) {
|
||||
xnum <<= +shift;
|
||||
} else if (shift < 0) {
|
||||
xden <<= -shift;
|
||||
}
|
||||
CGAL_assertion(num_dbl_digits + 1 ==
|
||||
static_cast<int64_t>(boost::multiprecision::msb(xnum)) -
|
||||
static_cast<int64_t>(boost::multiprecision::msb(xden)));
|
||||
|
||||
ET p, r;
|
||||
boost::multiprecision::divide_qr(xnum, xden, p, r);
|
||||
uint64_t uip = static_cast<uint64_t>(p);
|
||||
const int64_t p_bits = static_cast<int64_t>(boost::multiprecision::msb(p));
|
||||
bool exact = r.is_zero();
|
||||
|
||||
if (p_bits > num_dbl_digits) { // case 54 bits
|
||||
exact &= ((uip & 1) == 0);
|
||||
uip>>=1;
|
||||
--shift;
|
||||
}
|
||||
std::tie(l, u) = exact ? get_0ulp_interval(shift, uip) : get_1ulp_interval(shift, uip);
|
||||
|
||||
if (change_sign) {
|
||||
const double t = l;
|
||||
l = -u;
|
||||
u = -t;
|
||||
}
|
||||
|
||||
CGAL_assertion(are_bounds_correct(l, u, input));
|
||||
return std::make_pair(l, u);
|
||||
}
|
||||
|
||||
// This is a version of to_interval that converts an integer type into a
|
||||
// double tight interval.
|
||||
template<typename ET>
|
||||
std::pair<double, double> to_interval( ET x, int extra_shift) {
|
||||
|
||||
CGAL_assertion_code(const ET input = x);
|
||||
double l = 0.0, u = 0.0;
|
||||
if (CGAL::is_zero(x)) { // return [0.0, 0.0]
|
||||
CGAL_assertion(are_bounds_correct(l, u, input));
|
||||
return std::make_pair(l, u);
|
||||
}
|
||||
CGAL_assertion(!CGAL::is_zero(x));
|
||||
|
||||
bool change_sign = false;
|
||||
const bool is_pos = CGAL::is_positive(x);
|
||||
if (!is_pos) {
|
||||
change_sign = true;
|
||||
x = -x;
|
||||
}
|
||||
CGAL_assertion(CGAL::is_positive(x));
|
||||
|
||||
const int64_t n = static_cast<int64_t>(boost::multiprecision::msb(x)) + 1;
|
||||
const int64_t num_dbl_digits = std::numeric_limits<double>::digits;
|
||||
|
||||
if (n > num_dbl_digits) {
|
||||
const int64_t mindig = static_cast<int64_t>(boost::multiprecision::lsb(x));
|
||||
int e = static_cast<int>(n - num_dbl_digits);
|
||||
x >>= e;
|
||||
if (n - mindig > num_dbl_digits)
|
||||
std::tie(l, u) = get_1ulp_interval(-e+extra_shift, static_cast<uint64_t>(x));
|
||||
else
|
||||
std::tie(l, u) = get_0ulp_interval(-e+extra_shift, static_cast<uint64_t>(x));
|
||||
} else {
|
||||
l = u = extra_shift==0 ? static_cast<double>(static_cast<uint64_t>(x))
|
||||
: std::ldexp(static_cast<double>(static_cast<uint64_t>(x)),-extra_shift);
|
||||
}
|
||||
|
||||
if (change_sign) {
|
||||
const double t = l;
|
||||
l = -u;
|
||||
u = -t;
|
||||
}
|
||||
|
||||
CGAL_assertion(extra_shift != 0 || are_bounds_correct(l, u, input));
|
||||
return std::make_pair(l, u);
|
||||
}
|
||||
|
||||
} // Boost_MP_internal
|
||||
|
||||
template <class NT>
|
||||
struct RET_boost_mp_base
|
||||
: public INTERN_RET::Real_embeddable_traits_base< NT , CGAL::Tag_true > {
|
||||
|
||||
typedef NT Type;
|
||||
|
||||
struct Is_zero: public CGAL::cpp98::unary_function<Type ,bool> {
|
||||
bool operator()( const Type& x) const {
|
||||
return x.is_zero();
|
||||
}
|
||||
};
|
||||
|
||||
struct Is_positive: public CGAL::cpp98::unary_function<Type ,bool> {
|
||||
bool operator()( const Type& x) const {
|
||||
return x.sign() > 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct Is_negative: public CGAL::cpp98::unary_function<Type ,bool> {
|
||||
bool operator()( const Type& x) const {
|
||||
return x.sign() < 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct Abs : public CGAL::cpp98::unary_function<Type, Type> {
|
||||
template <typename T>
|
||||
Type operator()(const T& x) const {
|
||||
return boost::multiprecision::abs(x);
|
||||
}
|
||||
};
|
||||
|
||||
struct Sgn : public CGAL::cpp98::unary_function<Type, ::CGAL::Sign> {
|
||||
::CGAL::Sign operator()(Type const& x) const {
|
||||
return CGAL::sign(x.sign());
|
||||
}
|
||||
};
|
||||
|
||||
struct Compare
|
||||
: public CGAL::cpp98::binary_function<Type, Type, Comparison_result> {
|
||||
Comparison_result operator()(const Type& x, const Type& y) const {
|
||||
return CGAL::sign(x.compare(y));
|
||||
}
|
||||
};
|
||||
|
||||
struct To_double
|
||||
: public CGAL::cpp98::unary_function<Type, double> {
|
||||
double operator()(const Type& x) const {
|
||||
return x.template convert_to<double>();
|
||||
}
|
||||
};
|
||||
|
||||
struct To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
|
||||
std::pair<double, double>
|
||||
operator()(const Type& x) const {
|
||||
|
||||
// See if https://github.com/boostorg/multiprecision/issues/108 suggests anything better
|
||||
// assume the conversion is within 1 ulp
|
||||
// adding IA::smallest() doesn't work because inf-e=inf, even rounded down.
|
||||
|
||||
// We must use to_nearest here.
|
||||
double i;
|
||||
const double inf = std::numeric_limits<double>::infinity();
|
||||
{
|
||||
Protect_FPU_rounding<true> P(CGAL_FE_TONEAREST);
|
||||
i = static_cast<double>(x);
|
||||
if (i == +inf) {
|
||||
return std::make_pair((std::numeric_limits<double>::max)(), i);
|
||||
} else if (i == -inf) {
|
||||
return std::make_pair(i, std::numeric_limits<double>::lowest());
|
||||
}
|
||||
}
|
||||
double s = i;
|
||||
CGAL_assertion(CGAL::abs(i) != inf && CGAL::abs(s) != inf);
|
||||
|
||||
// Throws uncaught exception: Cannot convert a non-finite number to an integer.
|
||||
// We can catch it earlier by using the CGAL_assertion() one line above.
|
||||
const int cmp = x.compare(i);
|
||||
if (cmp > 0) {
|
||||
s = nextafter(s, +inf);
|
||||
CGAL_assertion(x.compare(s) < 0);
|
||||
}
|
||||
else if (cmp < 0) {
|
||||
i = nextafter(i, -inf);
|
||||
CGAL_assertion(x.compare(i) > 0);
|
||||
}
|
||||
return std::pair<double, double>(i, s);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class T, class = boost::mpl::int_<boost::multiprecision::number_category<T>::value> >
|
||||
struct RET_boost_mp;
|
||||
|
||||
template <class NT>
|
||||
struct RET_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_integer> >
|
||||
: RET_boost_mp_base <NT> {
|
||||
typedef NT Type;
|
||||
struct To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
|
||||
std::pair<double, double> operator()( const Type& x ) const {
|
||||
return Boost_MP_internal::to_interval(x);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class NT>
|
||||
struct RET_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_rational> >
|
||||
: RET_boost_mp_base <NT> {
|
||||
typedef NT Type;
|
||||
struct To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
|
||||
std::pair<double, double> operator()( const Type& x ) const {
|
||||
return Boost_MP_internal::to_interval<Type>(
|
||||
boost::multiprecision::numerator(x), boost::multiprecision::denominator(x));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef CGAL_USE_MPFR
|
||||
// Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary.
|
||||
template <>
|
||||
struct RET_boost_mp <boost::multiprecision::mpz_int>
|
||||
: RET_boost_mp_base <boost::multiprecision::mpz_int> {
|
||||
typedef boost::multiprecision::mpz_int Type;
|
||||
struct To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
std::pair<double, double>
|
||||
operator()(const Type& x) const {
|
||||
#if MPFR_VERSION_MAJOR >= 3
|
||||
MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */
|
||||
int r = mpfr_set_z (y, x.backend().data(), MPFR_RNDA);
|
||||
double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */
|
||||
if (r == 0 && is_finite (i))
|
||||
return std::pair<double, double>(i, i);
|
||||
else
|
||||
{
|
||||
double s = nextafter (i, 0);
|
||||
if (i < 0)
|
||||
return std::pair<double, double>(i, s);
|
||||
else
|
||||
return std::pair<double, double>(s, i);
|
||||
}
|
||||
#else
|
||||
mpfr_t y;
|
||||
mpfr_init2 (y, 53); /* Assume IEEE-754 */
|
||||
mpfr_set_z (y, x.backend().data(), GMP_RNDD);
|
||||
double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */
|
||||
mpfr_set_z (y, x.backend().data(), GMP_RNDU);
|
||||
double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */
|
||||
mpfr_clear (y);
|
||||
return std::pair<double, double>(i, s);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct RET_boost_mp <boost::multiprecision::mpq_rational>
|
||||
: RET_boost_mp_base <boost::multiprecision::mpq_rational> {
|
||||
typedef boost::multiprecision::mpq_rational Type;
|
||||
struct To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
std::pair<double, double>
|
||||
operator()(const Type& x) const {
|
||||
# if MPFR_VERSION_MAJOR >= 3
|
||||
mpfr_exp_t emin = mpfr_get_emin();
|
||||
mpfr_set_emin(-1073);
|
||||
MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */
|
||||
int r = mpfr_set_q (y, x.backend().data(), MPFR_RNDA);
|
||||
r = mpfr_subnormalize (y, r, MPFR_RNDA); /* Round subnormals */
|
||||
double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */
|
||||
mpfr_set_emin(emin); /* Restore old value, users may care */
|
||||
// With mpfr_set_emax(1024) we could drop the is_finite test
|
||||
if (r == 0 && is_finite (i))
|
||||
return std::pair<double, double>(i, i);
|
||||
else
|
||||
{
|
||||
double s = nextafter (i, 0);
|
||||
if (i < 0)
|
||||
return std::pair<double, double>(i, s);
|
||||
else
|
||||
return std::pair<double, double>(s, i);
|
||||
}
|
||||
# else
|
||||
mpfr_t y;
|
||||
mpfr_init2 (y, 53); /* Assume IEEE-754 */
|
||||
mpfr_set_q (y, x.backend().data(), GMP_RNDD);
|
||||
double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */
|
||||
mpfr_set_q (y, x.backend().data(), GMP_RNDU);
|
||||
double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */
|
||||
mpfr_clear (y);
|
||||
return std::pair<double, double>(i, s);
|
||||
# endif
|
||||
}
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Backend, boost::multiprecision::expression_template_option Eto>
|
||||
struct Real_embeddable_traits<boost::multiprecision::number<Backend, Eto> >
|
||||
: RET_boost_mp <boost::multiprecision::number<Backend, Eto> > {};
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
struct Real_embeddable_traits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> >
|
||||
: Real_embeddable_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type > {};
|
||||
|
||||
// Modular_traits
|
||||
|
||||
template <class T, class = boost::mpl::int_<boost::multiprecision::number_category<T>::value> >
|
||||
struct MT_boost_mp {
|
||||
typedef T NT;
|
||||
typedef ::CGAL::Tag_false Is_modularizable;
|
||||
typedef ::CGAL::Null_functor Residue_type;
|
||||
typedef ::CGAL::Null_functor Modular_image;
|
||||
typedef ::CGAL::Null_functor Modular_image_representative;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct MT_boost_mp <T, boost::mpl::int_<boost::multiprecision::number_kind_integer> > {
|
||||
typedef T NT;
|
||||
typedef CGAL::Tag_true Is_modularizable;
|
||||
typedef Residue Residue_type;
|
||||
|
||||
struct Modular_image{
|
||||
Residue_type operator()(const NT& a){
|
||||
NT tmp(CGAL::mod(a,NT(Residue::get_current_prime())));
|
||||
return CGAL::Residue(tmp.template convert_to<int>());
|
||||
}
|
||||
};
|
||||
struct Modular_image_representative{
|
||||
NT operator()(const Residue_type& x){
|
||||
return NT(x.get_value());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class Backend, boost::multiprecision::expression_template_option Eto>
|
||||
struct Modular_traits<boost::multiprecision::number<Backend, Eto> >
|
||||
: MT_boost_mp <boost::multiprecision::number<Backend, Eto> > {};
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
struct Modular_traits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> >
|
||||
: Modular_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type > {};
|
||||
|
||||
// Split_double
|
||||
|
||||
template <class NT, class = boost::mpl::int_<boost::multiprecision::number_category<NT>::value> >
|
||||
struct SD_boost_mp {
|
||||
void operator()(double d, NT &num, NT &den) const
|
||||
{
|
||||
num = d;
|
||||
den = 1;
|
||||
}
|
||||
};
|
||||
|
||||
template <class NT>
|
||||
struct SD_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_integer> >
|
||||
{
|
||||
void operator()(double d, NT &num, NT &den) const
|
||||
{
|
||||
std::pair<double, double> p = split_numerator_denominator(d);
|
||||
num = NT(p.first);
|
||||
den = NT(p.second);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Backend, boost::multiprecision::expression_template_option Eto>
|
||||
struct Split_double<boost::multiprecision::number<Backend, Eto> >
|
||||
: SD_boost_mp <boost::multiprecision::number<Backend, Eto> > {};
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
struct Split_double<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> >
|
||||
: Split_double<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type > {};
|
||||
|
||||
|
||||
// Fraction_traits
|
||||
|
||||
template <class T, class = boost::mpl::int_<boost::multiprecision::number_category<T>::value> >
|
||||
struct FT_boost_mp {
|
||||
typedef T Type;
|
||||
typedef Tag_false Is_fraction;
|
||||
typedef Null_tag Numerator_type;
|
||||
typedef Null_tag Denominator_type;
|
||||
typedef Null_functor Common_factor;
|
||||
typedef Null_functor Decompose;
|
||||
typedef Null_functor Compose;
|
||||
};
|
||||
|
||||
template <class NT>
|
||||
struct FT_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_rational> > {
|
||||
typedef NT Type;
|
||||
|
||||
typedef ::CGAL::Tag_true Is_fraction;
|
||||
typedef typename boost::multiprecision::component_type<NT>::type Numerator_type;
|
||||
typedef Numerator_type Denominator_type;
|
||||
|
||||
typedef typename Algebraic_structure_traits< Numerator_type >::Gcd Common_factor;
|
||||
|
||||
class Decompose {
|
||||
public:
|
||||
typedef Type first_argument_type;
|
||||
typedef Numerator_type& second_argument_type;
|
||||
typedef Denominator_type& third_argument_type;
|
||||
void operator () (
|
||||
const Type& rat,
|
||||
Numerator_type& num,
|
||||
Denominator_type& den) {
|
||||
num = numerator(rat);
|
||||
den = denominator(rat);
|
||||
}
|
||||
};
|
||||
|
||||
class Compose {
|
||||
public:
|
||||
typedef Numerator_type first_argument_type;
|
||||
typedef Denominator_type second_argument_type;
|
||||
typedef Type result_type;
|
||||
Type operator ()(
|
||||
const Numerator_type& num ,
|
||||
const Denominator_type& den ) {
|
||||
return Type(num, den);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class Backend, boost::multiprecision::expression_template_option Eto>
|
||||
struct Fraction_traits<boost::multiprecision::number<Backend, Eto> >
|
||||
: FT_boost_mp <boost::multiprecision::number<Backend, Eto> > {};
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
struct Fraction_traits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> >
|
||||
: Fraction_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type > {};
|
||||
|
||||
|
||||
// Coercions
|
||||
|
||||
namespace internal { namespace boost_mp { BOOST_MPL_HAS_XXX_TRAIT_DEF(type) } }
|
||||
|
||||
template <class B1, boost::multiprecision::expression_template_option E1, class B2, boost::multiprecision::expression_template_option E2>
|
||||
struct Coercion_traits<boost::multiprecision::number<B1, E1>, boost::multiprecision::number<B2, E2> >
|
||||
{
|
||||
typedef boost::common_type<boost::multiprecision::number<B1, E1>, boost::multiprecision::number<B2, E2> > CT;
|
||||
typedef Boolean_tag<internal::boost_mp::has_type<CT>::value> Are_implicit_interoperable;
|
||||
// FIXME: the implicit/explicit answers shouldn't be the same...
|
||||
typedef Are_implicit_interoperable Are_explicit_interoperable;
|
||||
// FIXME: won't compile when they are not interoperable.
|
||||
typedef typename CT::type Type;
|
||||
struct Cast{
|
||||
typedef Type result_type;
|
||||
template <class U>
|
||||
Type operator()(const U& x) const {
|
||||
return Type(x);
|
||||
}
|
||||
};
|
||||
};
|
||||
// Avoid ambiguity with the specialization for <A,A> ...
|
||||
template <class B1, boost::multiprecision::expression_template_option E1>
|
||||
struct Coercion_traits<boost::multiprecision::number<B1, E1>, boost::multiprecision::number<B1, E1> >
|
||||
{
|
||||
typedef boost::multiprecision::number<B1, E1> Type;
|
||||
typedef Tag_true Are_implicit_interoperable;
|
||||
typedef Tag_true Are_explicit_interoperable;
|
||||
struct Cast{
|
||||
typedef Type result_type;
|
||||
template <class U>
|
||||
Type operator()(const U& x) const {
|
||||
return Type(x);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class T1, class T2, class T3, class T4, class T5, class U1, class U2, class U3, class U4, class U5>
|
||||
struct Coercion_traits <
|
||||
boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>,
|
||||
boost::multiprecision::detail::expression<U1,U2,U3,U4,U5> >
|
||||
: Coercion_traits <
|
||||
typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type,
|
||||
typename boost::multiprecision::detail::expression<U1,U2,U3,U4,U5>::result_type>
|
||||
{ };
|
||||
// Avoid ambiguity with the specialization for <A,A> ...
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
struct Coercion_traits <
|
||||
boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>,
|
||||
boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> >
|
||||
: Coercion_traits <
|
||||
typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type,
|
||||
typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type>
|
||||
{ };
|
||||
|
||||
template <class B, boost::multiprecision::expression_template_option E, class T1, class T2, class T3, class T4, class T5>
|
||||
struct Coercion_traits<boost::multiprecision::number<B, E>, boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> >
|
||||
: Coercion_traits <
|
||||
boost::multiprecision::number<B, E>,
|
||||
typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type>
|
||||
{ };
|
||||
|
||||
template <class B, boost::multiprecision::expression_template_option E, class T1, class T2, class T3, class T4, class T5>
|
||||
struct Coercion_traits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>, boost::multiprecision::number<B, E> >
|
||||
: Coercion_traits <
|
||||
typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type,
|
||||
boost::multiprecision::number<B, E> >
|
||||
{ };
|
||||
|
||||
// TODO: fix existing coercions
|
||||
// (double -> rational is implicit only for 1.56+, see ticket #10082)
|
||||
// The real solution would be to avoid specializing Coercion_traits for all pairs of number types and let it auto-detect what works, so only broken types need an explicit specialization.
|
||||
|
||||
// Ignore types smaller than long
|
||||
#define CGAL_COERCE_INT(int) \
|
||||
template <class B1, boost::multiprecision::expression_template_option E1> \
|
||||
struct Coercion_traits<boost::multiprecision::number<B1, E1>, int> { \
|
||||
typedef boost::multiprecision::number<B1, E1> Type; \
|
||||
typedef Tag_true Are_implicit_interoperable; \
|
||||
typedef Tag_true Are_explicit_interoperable; \
|
||||
struct Cast{ \
|
||||
typedef Type result_type; \
|
||||
template <class U> Type operator()(const U& x) const { return Type(x); } \
|
||||
}; \
|
||||
}; \
|
||||
template <class B1, boost::multiprecision::expression_template_option E1> \
|
||||
struct Coercion_traits<int, boost::multiprecision::number<B1, E1> > \
|
||||
: Coercion_traits<boost::multiprecision::number<B1, E1>, int> {}; \
|
||||
template <class T1, class T2, class T3, class T4, class T5> \
|
||||
struct Coercion_traits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>, int> \
|
||||
: Coercion_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type, int>{}; \
|
||||
template <class T1, class T2, class T3, class T4, class T5> \
|
||||
struct Coercion_traits<int, boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> > \
|
||||
: Coercion_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type, int>{}
|
||||
|
||||
CGAL_COERCE_INT(short);
|
||||
CGAL_COERCE_INT(int);
|
||||
CGAL_COERCE_INT(long);
|
||||
#undef CGAL_COERCE_INT
|
||||
|
||||
// Ignore bounded-precision rationals
|
||||
#define CGAL_COERCE_FLOAT(float) \
|
||||
template <class B1, boost::multiprecision::expression_template_option E1> \
|
||||
struct Coercion_traits<boost::multiprecision::number<B1, E1>, float> { \
|
||||
typedef boost::multiprecision::number<B1, E1> Type; \
|
||||
typedef Boolean_tag<boost::multiprecision::number_category<Type>::value != boost::multiprecision::number_kind_integer> Are_implicit_interoperable; \
|
||||
typedef Are_implicit_interoperable Are_explicit_interoperable; \
|
||||
struct Cast{ \
|
||||
typedef Type result_type; \
|
||||
template <class U> Type operator()(const U& x) const { return Type(x); } \
|
||||
}; \
|
||||
}; \
|
||||
template <class B1, boost::multiprecision::expression_template_option E1> \
|
||||
struct Coercion_traits<float, boost::multiprecision::number<B1, E1> > \
|
||||
: Coercion_traits<boost::multiprecision::number<B1, E1>, float> {}; \
|
||||
template <class T1, class T2, class T3, class T4, class T5> \
|
||||
struct Coercion_traits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>, float> \
|
||||
: Coercion_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type, float>{}; \
|
||||
template <class T1, class T2, class T3, class T4, class T5> \
|
||||
struct Coercion_traits<float, boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> > \
|
||||
: Coercion_traits<typename boost::multiprecision::detail::expression<T1,T2,T3,T4,T5>::result_type, float>{}
|
||||
|
||||
CGAL_COERCE_FLOAT(float);
|
||||
CGAL_COERCE_FLOAT(double);
|
||||
#undef CGAL_COERCE_FLOAT
|
||||
|
||||
// Because of https://github.com/boostorg/multiprecision/issues/29 , this is not perfect and fails to read some KDS files.
|
||||
|
||||
template <>
|
||||
class Input_rep<boost::multiprecision::cpp_rational> : public IO_rep_is_specialized {
|
||||
boost::multiprecision::cpp_rational& q;
|
||||
public:
|
||||
Input_rep(boost::multiprecision::cpp_rational& qq) : q(qq) {}
|
||||
std::istream& operator()(std::istream& in) const {
|
||||
internal::read_float_or_quotient<boost::multiprecision::cpp_int,boost::multiprecision::cpp_rational>(in, q);
|
||||
return in;
|
||||
}
|
||||
};
|
||||
#ifdef CGAL_USE_GMP
|
||||
template <>
|
||||
class Input_rep<boost::multiprecision::mpq_rational> : public IO_rep_is_specialized {
|
||||
boost::multiprecision::mpq_rational& q;
|
||||
public:
|
||||
Input_rep(boost::multiprecision::mpq_rational& qq) : q(qq) {}
|
||||
std::istream& operator()(std::istream& in) const {
|
||||
internal::read_float_or_quotient<boost::multiprecision::mpz_int,boost::multiprecision::mpq_rational>(in, q);
|
||||
return in;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Copied from leda_rational.h
|
||||
namespace internal {
|
||||
// See: Stream_support/include/CGAL/IO/io.h
|
||||
template <typename ET>
|
||||
void read_float_or_quotient(std::istream & is, ET& et);
|
||||
|
||||
template <>
|
||||
inline void read_float_or_quotient(std::istream & is, boost::multiprecision::cpp_rational& et)
|
||||
{
|
||||
internal::read_float_or_quotient<boost::multiprecision::cpp_int,boost::multiprecision::cpp_rational>(is, et);
|
||||
}
|
||||
#ifdef CGAL_USE_GMP
|
||||
template <>
|
||||
inline void read_float_or_quotient(std::istream & is, boost::multiprecision::mpq_rational& et)
|
||||
{
|
||||
internal::read_float_or_quotient<boost::multiprecision::mpz_int,boost::multiprecision::mpq_rational>(is, et);
|
||||
}
|
||||
#endif
|
||||
} // namespace internal
|
||||
|
||||
#ifdef CGAL_USE_BOOST_MP
|
||||
|
||||
template< > class Real_embeddable_traits< Quotient<boost::multiprecision::cpp_int> >
|
||||
: public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< Quotient<boost::multiprecision::cpp_int> > {
|
||||
|
||||
public:
|
||||
typedef Quotient<boost::multiprecision::cpp_int> Type;
|
||||
|
||||
class To_interval
|
||||
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
|
||||
public:
|
||||
std::pair<double, double> operator()( const Type& x ) const {
|
||||
return Boost_MP_internal::to_interval<Type>(x.num, x.den);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // CGAL_USE_BOOST_MP
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#include <CGAL/boost_mp_type.h>
|
||||
#include <CGAL/BOOST_MP_arithmetic_kernel.h>
|
||||
#include <CGAL/cpp_float.h>
|
||||
|
||||
#endif // BOOST_VERSION
|
||||
#endif
|
||||
#endif // CGAL_BOOST_MP_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -13,10 +13,6 @@ include_directories(BEFORE include)
|
|||
create_single_source_cgal_program("bench_interval.cpp")
|
||||
create_single_source_cgal_program("cpp_float.cpp")
|
||||
create_single_source_cgal_program("constant.cpp")
|
||||
create_single_source_cgal_program("CORE_BigFloat.cpp")
|
||||
create_single_source_cgal_program("CORE_BigInt.cpp")
|
||||
create_single_source_cgal_program("CORE_BigRat.cpp")
|
||||
create_single_source_cgal_program("CORE_Expr.cpp")
|
||||
create_single_source_cgal_program("Counted_number.cpp")
|
||||
create_single_source_cgal_program("double.cpp")
|
||||
create_single_source_cgal_program("doubletst.cpp")
|
||||
|
|
@ -66,14 +62,17 @@ create_single_source_cgal_program("utilities.cpp")
|
|||
create_single_source_cgal_program("Exact_rational.cpp")
|
||||
create_single_source_cgal_program("Mpzf_new.cpp")
|
||||
|
||||
find_package( GMP )
|
||||
if( GMP_FOUND AND NOT CGAL_DISABLE_GMP )
|
||||
if( CGAL_Core_FOUND )
|
||||
create_single_source_cgal_program( "CORE_Expr_ticket_4296.cpp" )
|
||||
create_single_source_cgal_program("CORE_BigFloat.cpp")
|
||||
create_single_source_cgal_program("CORE_BigInt.cpp")
|
||||
create_single_source_cgal_program("CORE_BigRat.cpp")
|
||||
create_single_source_cgal_program("CORE_Expr.cpp")
|
||||
find_package(MPFI QUIET)
|
||||
if( MPFI_FOUND )
|
||||
include( ${MPFI_USE_FILE} )
|
||||
endif() #MPFI_FOUND
|
||||
endif() #GMP_FOUND AND NOT CGAL_DISABLE_GMP
|
||||
endif() #CGAL_Core_FOUND
|
||||
|
||||
if(NOT CGAL_DISABLE_GMP)
|
||||
create_single_source_cgal_program( "Gmpfi.cpp" )
|
||||
|
|
|
|||
|
|
@ -72,4 +72,3 @@ int main() { return 0; }
|
|||
#endif // CGAL_USE_CORE
|
||||
|
||||
//EOF
|
||||
|
||||
|
|
|
|||
|
|
@ -19,24 +19,25 @@ 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
|
||||
{
|
||||
std::stringstream ss;
|
||||
CGAL::IO::set_pretty_mode(ss);
|
||||
ss << CGAL::IO::oformat(NT(2), CGAL::Parens_as_product_tag());
|
||||
std::cout << "|" << ss.str() << "|" << std::endl;
|
||||
assert( ss.str() == "2");
|
||||
}{
|
||||
std::stringstream ss;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <cstdlib>
|
||||
|
||||
#include <CGAL/CORE_Expr.h>
|
||||
#include <CGAL/Gmpq.h>
|
||||
#include <CGAL/CORE_BigRat.h>
|
||||
#include <CGAL/Test/_test_algebraic_structure.h>
|
||||
#include <CGAL/Test/_test_real_embeddable.h>
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ void test_MSB_bug()
|
|||
int main() {
|
||||
precision_bug();
|
||||
test_istream();
|
||||
test_MSB_bug<CGAL::Gmpq>();
|
||||
test_MSB_bug<CORE::BigRat>();
|
||||
test_MSB_bug<CORE::Expr>();
|
||||
|
||||
typedef CORE::Expr NT;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ int main()
|
|||
|
||||
// CORE
|
||||
#ifdef CGAL_USE_CORE
|
||||
static_assert(CGAL::Output_rep<CORE::BigRat>::is_specialized == true);
|
||||
//bug in io for CORE.
|
||||
test_it<CORE::BigInt>("CORE::BigInt");
|
||||
test_it<CORE::BigRat>("CORE::BigRat");
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#ifdef CGAL_EIGEN3_ENABLED
|
||||
#include <Eigen/Dense>
|
||||
|
||||
|
||||
|
||||
// Just check that it all compiles.
|
||||
template <class NT, int s>
|
||||
void check_(){
|
||||
|
|
@ -33,7 +35,7 @@ void check_(){
|
|||
Eigen::Matrix<NT,s,1> v(3);
|
||||
v << 1, 2, 3;
|
||||
NT t=v.dot(v);
|
||||
v+=d*m*(t*v);
|
||||
v+=d*Eigen::Matrix<NT,s,1>(m*(t*v));
|
||||
std::ptrdiff_t si=v.size();
|
||||
CGAL_USE(si);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@
|
|||
#include <CGAL/Lazy_exact_nt.h>
|
||||
#include <CGAL/Interval_nt.h>
|
||||
#include <CGAL/Sqrt_extension.h>
|
||||
|
||||
#ifdef CGAL_USE_BOOST_MP
|
||||
#include <CGAL/boost_mp.h>
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_USE_GMP
|
||||
#include <CGAL/Gmpz.h>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
Arithmetic_kernel
|
||||
BGL
|
||||
Bounding_volumes
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Convex_hull_2
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Convex_hull_2
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Convex_hull_2
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
CGAL_Core
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Distance_2
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue