unsigned return_type_tinfo(void) const;
ex thisexpairseq(epvector const & v, ex const & oc) const;
ex thisexpairseq(epvector * vp, ex const & oc) const;
- void printpair(ostream & os, expair const & p,
- unsigned upper_precedence) const;
expair split_ex_to_pair(ex const & e) const;
expair combine_ex_with_coeff_to_pair(ex const & e,
ex const & c) const;
unsigned return_type_tinfo(void) const;
ex thisexpairseq(epvector const & v, ex const & oc) const;
ex thisexpairseq(epvector * vp, ex const & oc) const;
- void printpair(ostream & os, expair const & p,
- unsigned upper_precedence) const;
expair split_ex_to_pair(ex const & e) const;
expair combine_ex_with_coeff_to_pair(ex const & e,
ex const & c) const;
void numeric::print(ostream & os, unsigned upper_precedence) const
{
debugmsg("numeric print", LOGLEVEL_PRINT);
- if (is_real()) {
+ if (is_real()) {
// case 1, real: x or -x
if ((precedence<=upper_precedence) && (!is_pos_integer())) {
os << "(" << *value << ")";
return operator=(numeric(s));
}
+/** Return the complex half-plane (left or right) in which the number lies.
+ * csgn(x)==0 for x==0, csgn(x)==1 for Re(x)>0 or Re(x)=0 and Im(x)>0,
+ * csgn(x)==-1 for Re(x)<0 or Re(x)=0 and Im(x)<0.
+ *
+ * @see numeric::compare(numeric const @ other) */
+int numeric::csgn(void) const
+{
+ if (is_zero())
+ return 0;
+ if (!zerop(realpart(*value))) {
+ if (plusp(realpart(*value)))
+ return 1;
+ else
+ return -1;
+ } else {
+ if (plusp(imagpart(*value)))
+ return 1;
+ else
+ return -1;
+ }
+}
+
/** This method establishes a canonical order on all numbers. For complex
* numbers this is not possible in a mathematically consistent way but we need
* to establish some order and it ought to be fast. So we simply define it
- * similar to Maple's csgn. */
+ * to be compatible with our method csgn.
+ *
+ * @return csgn(*this-other)
+ * @see numeric::csgn(void) */
int numeric::compare(numeric const & other) const
{
// Comparing two real numbers?
* @exception range_error (argument must be integer >= -1) */
numeric doublefactorial(numeric const & nn)
{
+ // META-NOTE: The whole shit here will become obsolete and may be moved
+ // out once CLN learns about double factorial, which should be as soon as
+ // 1.0.3 rolls out.
+
// We store the results separately for even and odd arguments. This has
// the advantage that we don't have to compute any even result at all if
// the function is always called with odd arguments and vice versa. There
numeric power_dyn(numeric const & other) const { return power(other); }
*/
numeric inverse(void) const;
+ int csgn(void) const;
int compare(numeric const & other) const;
bool is_equal(numeric const & other) const;
bool is_zero(void) const;
inline numeric inverse(numeric const & x)
{ return x.inverse(); }
+inline bool csgn(numeric const & x)
+{ return x.csgn(); }
+
inline bool is_zero(numeric const & x)
{ return x.is_zero(); }
os << "]]";
}
-void add::printpair(ostream & os, expair const & p, unsigned upper_precedence) const
-{
- os << "(";
- if (p.coeff == -1) {
- os << "-";
- } else {
- if (p.coeff != 1) {
- os << p.coeff;
- os << "*";
- }
- }
- os << p.rest;
- os << ")";
-}
-
void add::print(ostream & os, unsigned upper_precedence) const
{
debugmsg("add print",LOGLEVEL_PRINT);
if (precedence<=upper_precedence) os << "(";
+ numeric coeff;
bool first=true;
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
+ coeff = ex_to_numeric(cit->coeff);
if (!first) {
- if (cit->coeff > 0) os << '+';
+ if (coeff < 0) os << '-'; else os << '+';
} else {
+ if (coeff < 0) os << '-';
first=false;
}
- if (cit->coeff == -1) {
- os << "-";
- } else {
- if (cit->coeff != 1) {
- (cit->coeff).print(os,precedence);
- os << "*";
- }
+ if (coeff.compare(numONE()) && coeff.compare(numMINUSONE())) {
+ if (!coeff.is_real() && !coeff.real().is_zero()) os << '(';
+ if (coeff > 0)
+ os << coeff;
+ else
+ os << numeric(-1)*coeff;
+ if (!coeff.is_real() && !coeff.real().is_zero()) os << ')';
+ os << '*';
}
os << cit->rest;
}
+ // print the overall numeric coefficient, if present:
if (!overall_coeff.is_zero()) {
if (overall_coeff > 0) os << '+';
os << overall_coeff;
if (precedence<=upper_precedence) os << ")";
}
-void mul::printpair(ostream & os, expair const & p, unsigned upper_precedence) const
-{
- os << "(";
- if (p.coeff.compare(exONE())==0) {
- p.rest.print(os,upper_precedence);
- } else {
- // outer parens around ex needed for broken gcc-2.95 parser:
- (ex(power(p.rest,p.coeff))).print(os,upper_precedence);
- }
- os << ")";
-}
-
void mul::print(ostream & os, unsigned upper_precedence) const
{
debugmsg("mul print",LOGLEVEL_PRINT);