Exemplo n.º 1
0
MP_Float
operator*(const MP_Float &a, const MP_Float &b)
{
  if (a.is_zero() || b.is_zero())
    return MP_Float();

  // Disabled until square() is fixed.
  // if (&a == &b)
  //   return square(a);

  MP_Float r;
  r.exp = a.exp + b.exp;
  CGAL_assertion_msg(CGAL::abs(r.exp) < (1<<30)*1.0*(1<<23),
                     "Exponent overflow in MP_Float multiplication");
  r.v.assign(a.v.size() + b.v.size(), 0);
  for(unsigned i = 0; i < a.v.size(); ++i)
  {
    unsigned j;
    MP_Float::limb carry = 0;
    for(j = 0; j < b.v.size(); ++j)
    {
      MP_Float::limb2 tmp = carry + (MP_Float::limb2) r.v[i+j]
                        + std::multiplies<MP_Float::limb2>()(a.v[i], b.v[j]);
      MP_Float::split(tmp, carry, r.v[i+j]);
    }
    r.v[i+j] = carry;
  }
  r.canonicalize();
  return r;
}
Exemplo n.º 2
0
  ~Check_FPU_rounding_mode_is_restored()
  {
    CGAL_assertion_msg( FPU_get_cw() == mode, 
		      "The default FPU rounding mode has not been restored "
		      " before the exit of the program. "
		      "That may be a bug in some CGAL kernel code.");
  }
Exemplo n.º 3
0
// FIXME : This function deserves proper testing...
pair<double,double>
INTERN_MP_FLOAT::to_interval(const Quotient<MP_Float> &q)
{
  pair<pair<double, double>, int> n = to_interval_exp(q.numerator());
  pair<pair<double, double>, int> d = to_interval_exp(q.denominator());
  CGAL_assertion_msg(CGAL::abs(1.0*n.second - d.second) < (1<<30)*2.0,
                     "Exponent overflow in Quotient<MP_Float> to_interval");
  return ldexp(Interval_nt<>(n.first) / Interval_nt<>(d.first),
               n.second - d.second).pair();
}
Exemplo n.º 4
0
// Returns (first * 2^second), an interval surrounding b.
pair<pair<double, double>, int>
to_interval_exp(const MP_Float &b)
{
  if (b.is_zero())
    return std::make_pair(pair<double, double>(0, 0), 0);

  exponent_type exp = b.max_exp();
  int steps = static_cast<int>((std::min)(limbs_per_double, b.v.size()));
  double d_exp_1 = std::ldexp(1.0, - (int) log_limb);
  double d_exp   = 1.0;

  Interval_nt_advanced::Protector P;
  Interval_nt_advanced d = 0;

  exponent_type i;
  for (i = exp - 1; i > exp - 1 - steps; i--) {
    d_exp *= d_exp_1;
    if (d_exp == 0) // Take care of underflow.
      d_exp = CGAL_IA_MIN_DOUBLE;
    d += d_exp * b.of_exp(i);
  }

  if (i >= b.min_exp() && d.is_point()) {
    if (b.of_exp(i) > 0)
      d += Interval_nt_advanced(0, d_exp);
    else if (b.of_exp(i) < 0)
      d += Interval_nt_advanced(-d_exp, 0);
    else
      d += Interval_nt_advanced(-d_exp, d_exp);
  }

#ifdef CGAL_EXPENSIVE_ASSERTION // force it always in early debugging
  if (d.is_point())
    CGAL_assertion(MP_Float(d.inf()) == b);
  else
    CGAL_assertion(MP_Float(d.inf()) <= b & MP_Float(d.sup()) >= b);
#endif

  CGAL_assertion_msg(CGAL::abs(exp*log_limb) < (1<<30)*2.0,
                     "Exponent overflow in MP_Float to_interval");
  return std::make_pair(d.pair(), static_cast<int>(exp * log_limb));
}
Exemplo n.º 5
0
// Returns (first * 2^second), an approximation of b.
pair<double, int>
to_double_exp(const MP_Float &b)
{
  if (b.is_zero())
    return std::make_pair(0.0, 0);

  exponent_type exp = b.max_exp();
  int steps = static_cast<int>((std::min)(limbs_per_double, b.v.size()));
  double d_exp_1 = std::ldexp(1.0, - static_cast<int>(log_limb));
  double d_exp   = 1.0;
  double d = 0;

  for (exponent_type i = exp - 1; i > exp - 1 - steps; i--) {
    d_exp *= d_exp_1;
    d += d_exp * b.of_exp(i);
  }

  CGAL_assertion_msg(CGAL::abs(exp*log_limb) < (1<<30)*2.0,
                     "Exponent overflow in MP_Float to_double");

  return std::make_pair(d, static_cast<int>(exp * log_limb));
}
Exemplo n.º 6
0
MP_Float
approximate_division(const MP_Float &a, const MP_Float &b)
{
  CGAL_assertion_msg(! b.is_zero(), " Division by zero");
  return MP_Float(CGAL::to_double(a)/CGAL::to_double(b));
}
Exemplo n.º 7
0
Line_d<R> Segment_d<R>::supporting_line() const
{   CGAL_assertion_msg((!is_degenerate()),
                       "Segment_d::supporting_line(): degenerate segment cannot be converted.");
    return Line_d<R>(Base(*this));
}