From: Jens Vollinga Date: Fri, 7 Sep 2007 18:48:22 +0000 (+0000) Subject: Improved CLN output [Sheplyakov]. X-Git-Tag: release_1-5-0~136 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=a5196f57af6539d8a25a866ad9cf8d836dd8e3df;hp=886ff58c2675aee6bd37469ce966924b40cc448d Improved CLN output [Sheplyakov]. --- diff --git a/ginac/add.cpp b/ginac/add.cpp index b37ab79d..98e8c798 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "add.h" #include "mul.h" @@ -172,37 +173,32 @@ void add::do_print_csrc(const print_csrc & c, unsigned level) const if (precedence() <= level) c.s << "("; - // Print arguments, separated by "+" + // Print arguments, separated by "+" or "-" epvector::const_iterator it = seq.begin(), itend = seq.end(); + char separator = ' '; while (it != itend) { - // If the coefficient is -1, it is replaced by a single minus sign - if (it->coeff.is_equal(_ex1)) { + // If the coefficient is negative, separator is "-" + if (it->coeff.is_equal(_ex_1) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + separator = '-'; + c.s << separator; + if (it->coeff.is_equal(_ex1) || it->coeff.is_equal(_ex_1)) { it->rest.print(c, precedence()); - } else if (it->coeff.is_equal(_ex_1)) { - c.s << "-"; + } else if (ex_to(it->coeff).numer().is_equal(*_num1_p) || + ex_to(it->coeff).numer().is_equal(*_num_1_p)) + { it->rest.print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num1_p)) { - it->rest.print(c, precedence()); - c.s << "/"; - ex_to(it->coeff).denom().print(c, precedence()); - } else if (ex_to(it->coeff).numer().is_equal(*_num_1_p)) { - c.s << "-"; - it->rest.print(c, precedence()); - c.s << "/"; + c.s << '/'; ex_to(it->coeff).denom().print(c, precedence()); } else { it->coeff.print(c, precedence()); - c.s << "*"; + c.s << '*'; it->rest.print(c, precedence()); } - // Separator is "+", except if the following expression would have a leading minus sign or the sign is sitting in parenthesis (as in a ctor) ++it; - if (it != itend - && (is_a(c) || !it->coeff.info(info_flags::real) // sign inside ctor arguments - || !(it->coeff.info(info_flags::negative) || (it->coeff.is_equal(*_num1_p) && is_exactly_a(it->rest) && it->rest.info(info_flags::negative))))) - c.s << "+"; + separator = '+'; } if (!overall_coeff.is_zero()) { diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index ef61ce75..3ca4b58c 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -399,6 +399,40 @@ static void print_real_csrc(const print_context & c, const cln::cl_R & x) } } +template +static inline bool coerce(T1& dst, const T2& arg); + +/** + * @brief Check if CLN integer can be converted into int + * + * @sa http://www.ginac.de/pipermail/cln-list/2006-October/000248.html + */ +template<> +static inline bool coerce(int& dst, const cln::cl_I& arg) +{ + static const cln::cl_I cl_max_int = + (cln::cl_I)(long)(std::numeric_limits::max()); + static const cln::cl_I cl_min_int = + (cln::cl_I)(long)(std::numeric_limits::min()); + if ((arg >= cl_min_int) && (arg <= cl_max_int)) { + dst = cl_I_to_int(arg); + return true; + } + return false; +} + +template<> +static inline bool coerce(unsigned int& dst, const cln::cl_I& arg) +{ + static const cln::cl_I cl_max_uint = + (cln::cl_I)(unsigned long)(std::numeric_limits::max()); + if ((! minusp(arg)) && (arg <= cl_max_uint)) { + dst = cl_I_to_uint(arg); + return true; + } + return false; +} + /** Helper function to print real number in C++ source format using cl_N types. * * @see numeric::print() */ @@ -406,11 +440,20 @@ static void print_real_cl_N(const print_context & c, const cln::cl_R & x) { if (cln::instanceof(x, cln::cl_I_ring)) { - // Integer number - c.s << "cln::cl_I(\""; - print_real_number(c, x); - c.s << "\")"; - + int dst; + // fixnum + if (coerce(dst, cln::the(x))) { + // can be converted to native int + if (dst < 0) + c.s << "(-" << dst << ")"; + else + c.s << dst; + } else { + // bignum + c.s << "cln::cl_I(\""; + print_real_number(c, x); + c.s << "\")"; + } } else if (cln::instanceof(x, cln::cl_RA_ring)) { // Rational number diff --git a/ginac/power.cpp b/ginac/power.cpp index faa0d05c..68bec71c 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -50,7 +50,8 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(power, basic, print_func(&power::do_print_latex). print_func(&power::do_print_csrc). print_func(&power::do_print_python). - print_func(&power::do_print_python_repr)) + print_func(&power::do_print_python_repr). + print_func(&power::do_print_csrc_cl_N)) typedef std::vector intvector; @@ -162,6 +163,21 @@ static void print_sym_pow(const print_context & c, const symbol &x, int exp) } } +void power::do_print_csrc_cl_N(const print_csrc_cl_N& c, unsigned level) const +{ + if (exponent.is_equal(_ex_1)) { + c.s << "recip("; + basis.print(c); + c.s << ')'; + return; + } + c.s << "expt("; + basis.print(c); + c.s << ", "; + exponent.print(c); + c.s << ')'; +} + void power::do_print_csrc(const print_csrc & c, unsigned level) const { // Integer powers of symbols are printed in a special, optimized way @@ -172,29 +188,20 @@ void power::do_print_csrc(const print_csrc & c, unsigned level) const c.s << '('; else { exp = -exp; - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; } print_sym_pow(c, ex_to(basis), exp); c.s << ')'; // ^-1 is printed as "1.0/" or with the recip() function of CLN } else if (exponent.is_equal(_ex_1)) { - if (is_a(c)) - c.s << "recip("; - else - c.s << "1.0/("; + c.s << "1.0/("; basis.print(c); c.s << ')'; - // Otherwise, use the pow() or expt() (CLN) functions + // Otherwise, use the pow() function } else { - if (is_a(c)) - c.s << "expt("; - else - c.s << "pow("; + c.s << "pow("; basis.print(c); c.s << ','; exponent.print(c); diff --git a/ginac/power.h b/ginac/power.h index f5e65d6a..3375040f 100644 --- a/ginac/power.h +++ b/ginac/power.h @@ -88,6 +88,7 @@ protected: void do_print_csrc(const print_csrc & c, unsigned level) const; void do_print_python(const print_python & c, unsigned level) const; void do_print_python_repr(const print_python_repr & c, unsigned level) const; + void do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const; ex expand_add(const add & a, int n, unsigned options) const; ex expand_add_2(const add & a, unsigned options) const;