* of special functions or implement the interface to the bignum package. */
/*
- * GiNaC Copyright (C) 1999-2002 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
!is_a<print_latex>(c)) {
cln::print_real(c.s, ourflags, x);
} else { // rational output in LaTeX context
+ if (x < 0)
+ c.s << "-";
c.s << "\\frac{";
- cln::print_real(c.s, ourflags, cln::numerator(cln::the<cln::cl_RA>(x)));
+ cln::print_real(c.s, ourflags, cln::abs(cln::numerator(cln::the<cln::cl_RA>(x))));
c.s << "}{";
cln::print_real(c.s, ourflags, cln::denominator(cln::the<cln::cl_RA>(x)));
c.s << '}';
std::ios::fmtflags oldflags = c.s.flags();
c.s.setf(std::ios::scientific);
- if (this->is_rational() && !this->is_integer()) {
+ int oldprec = c.s.precision();
+ if (is_a<print_csrc_double>(c))
+ c.s.precision(16);
+ else
+ c.s.precision(7);
+ if (is_a<print_csrc_cl_N>(c) && this->is_integer()) {
+ c.s << "cln::cl_I(\"";
+ const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
+ print_real_number(c,r);
+ c.s << "\")";
+ } else if (this->is_rational() && !this->is_integer()) {
if (compare(_num0) > 0) {
c.s << "(";
if (is_a<print_csrc_cl_N>(c))
c.s << ")";
} else {
if (is_a<print_csrc_cl_N>(c))
- c.s << "cln::cl_F(\"" << evalf() << "\")";
+ c.s << "cln::cl_F(\"" << evalf() << "_" << Digits << "\")";
else
c.s << to_double();
}
c.s.flags(oldflags);
+ c.s.precision(oldprec);
} else {
const std::string par_open = is_a<print_latex>(c) ? "{(" : "(";
} else {
if (cln::zerop(r)) {
// case 2, imaginary: y*I or -y*I
- if ((precedence() <= level) && (i < 0)) {
- if (i == -1) {
- c.s << par_open+imag_sym+par_close;
- } else {
+ if (i==1)
+ c.s << imag_sym;
+ else {
+ if (precedence()<=level)
c.s << par_open;
+ if (i == -1)
+ c.s << "-" << imag_sym;
+ else {
print_real_number(c, i);
- c.s << mul_sym+imag_sym+par_close;
- }
- } else {
- if (i == 1) {
- c.s << imag_sym;
- } else {
- if (i == -1) {
- c.s << "-" << imag_sym;
- } else {
- print_real_number(c, i);
- c.s << mul_sym+imag_sym;
- }
+ c.s << mul_sym+imag_sym;
}
+ if (precedence()<=level)
+ c.s << par_close;
}
} else {
// case 3, complex: x+y*I or x-y*I or -x+y*I or -x-y*I
return false;
}
+int numeric::degree(const ex & s) const
+{
+ return 0;
+}
+
+int numeric::ldegree(const ex & s) const
+{
+ return 0;
+}
+
+ex numeric::coeff(const ex & s, int n) const
+{
+ return n==0 ? *this : _ex0;
+}
+
/** Disassemble real part and imaginary part to scan for the occurrence of a
* single number. Also handles the imaginary unit. It ignores the sign on
* both this and the argument, which may lead to what might appear as funny
// algorithm not applicable to B(2), so just store it
if (!next_r) {
- results.push_back(); // results[0] is not used
results.push_back(cln::recip(cln::cl_RA(6)));
next_r = 4;
}
if (n<next_r)
- return results[n/2];
+ return results[n/2-1];
- results.reserve(n/2 + 1);
+ results.reserve(n/2);
for (unsigned p=next_r; p<=n; p+=2) {
cln::cl_I c = 1; // seed for binonmial coefficients
cln::cl_RA b = cln::cl_RA(1-p)/2;
if (p < (1UL<<cl_value_len/2)) {
for (i=2, k=1, p_2=p/2; i<=pm; i+=2, ++k, --p_2) {
c = cln::exquo(c * ((p3-i) * p_2), (i-1)*k);
- b = b + c*results[k];
+ b = b + c*results[k-1];
}
} else {
for (i=2, k=1, p_2=p/2; i<=pm; i+=2, ++k, --p_2) {
c = cln::exquo((c * (p3-i)) * p_2, cln::cl_I(i-1)*k);
- b = b + c*results[k];
+ b = b + c*results[k-1];
}
}
results.push_back(-b/(p+1));
}
next_r = n+2;
- return results[n/2];
+ return results[n/2-1];
}
* In general, mod(a,b) has the sign of b or is zero, and irem(a,b) has the
* sign of a or is zero.
*
- * @return remainder of a/b if both are integer, 0 otherwise. */
+ * @return remainder of a/b if both are integer, 0 otherwise.
+ * @exception overflow_error (division by zero) if b is zero. */
const numeric irem(const numeric &a, const numeric &b)
{
+ if (b.is_zero())
+ throw std::overflow_error("numeric::irem(): division by zero");
if (a.is_integer() && b.is_integer())
return cln::rem(cln::the<cln::cl_I>(a.to_cl_N()),
cln::the<cln::cl_I>(b.to_cl_N()));
* and irem(a,b) has the sign of a or is zero.
*
* @return remainder of a/b and quotient stored in q if both are integer,
- * 0 otherwise. */
+ * 0 otherwise.
+ * @exception overflow_error (division by zero) if b is zero. */
const numeric irem(const numeric &a, const numeric &b, numeric &q)
{
+ if (b.is_zero())
+ throw std::overflow_error("numeric::irem(): division by zero");
if (a.is_integer() && b.is_integer()) {
const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
cln::the<cln::cl_I>(b.to_cl_N()));
/** Numeric integer quotient.
* Equivalent to Maple's iquo as far as sign conventions are concerned.
*
- * @return truncated quotient of a/b if both are integer, 0 otherwise. */
+ * @return truncated quotient of a/b if both are integer, 0 otherwise.
+ * @exception overflow_error (division by zero) if b is zero. */
const numeric iquo(const numeric &a, const numeric &b)
{
+ if (b.is_zero())
+ throw std::overflow_error("numeric::iquo(): division by zero");
if (a.is_integer() && b.is_integer())
return cln::truncate1(cln::the<cln::cl_I>(a.to_cl_N()),
cln::the<cln::cl_I>(b.to_cl_N()));
* r == a - iquo(a,b,r)*b.
*
* @return truncated quotient of a/b and remainder stored in r if both are
- * integer, 0 otherwise. */
+ * integer, 0 otherwise.
+ * @exception overflow_error (division by zero) if b is zero. */
const numeric iquo(const numeric &a, const numeric &b, numeric &r)
{
+ if (b.is_zero())
+ throw std::overflow_error("numeric::iquo(): division by zero");
if (a.is_integer() && b.is_integer()) {
const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
cln::the<cln::cl_I>(b.to_cl_N()));