X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fnumeric.cpp;h=f8e4d93b406222046357042188ad12acb42ef9df;hp=c69a117d3748c0da1ed9fd26385143b5529a2361;hb=def23d34c68a383ce3d7da0227b984c8291a3bf9;hpb=68fdf425abf14d016d5f95ee7b9d06a19a3c5926 diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index c69a117d..f8e4d93b 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -34,7 +34,6 @@ #include "numeric.h" #include "ex.h" -#include "print.h" #include "operators.h" #include "archive.h" #include "tostring.h" @@ -61,7 +60,13 @@ namespace GiNaC { -GINAC_IMPLEMENT_REGISTERED_CLASS(numeric, basic) +GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(numeric, basic, + print_func(&numeric::do_print). + print_func(&numeric::do_print_latex). + print_func(&numeric::do_print_csrc). + print_func(&numeric::do_print_csrc_cl_N). + print_func(&numeric::do_print_tree). + print_func(&numeric::do_print_python_repr)) ////////// // default constructor @@ -410,140 +415,148 @@ static void print_real_cl_N(const print_context & c, const cln::cl_R & x) } } -/** This method adds to the output so it blends more consistently together - * with the other routines and produces something compatible to ginsh input. - * - * @see print_real_number() */ -void numeric::print(const print_context & c, unsigned level) const +void numeric::print_numeric(const print_context & c, const char *par_open, const char *par_close, const char *imag_sym, const char *mul_sym, unsigned level) const { - if (is_a(c)) { + const cln::cl_R r = cln::realpart(cln::the(value)); + const cln::cl_R i = cln::imagpart(cln::the(value)); - c.s << std::string(level, ' ') << cln::the(value) - << " (" << class_name() << ")" - << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec - << std::endl; + if (cln::zerop(i)) { - } else if (is_a(c)) { + // case 1, real: x or -x + if ((precedence() <= level) && (!this->is_nonneg_integer())) { + c.s << par_open; + print_real_number(c, r); + c.s << par_close; + } else { + print_real_number(c, r); + } - // CLN output - if (this->is_real()) { + } else { + if (cln::zerop(r)) { - // Real number - print_real_cl_N(c, cln::the(value)); + // case 2, imaginary: y*I or -y*I + 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; + } + if (precedence()<=level) + c.s << par_close; + } } else { - // Complex number - c.s << "cln::complex("; - print_real_cl_N(c, cln::realpart(cln::the(value))); - c.s << ","; - print_real_cl_N(c, cln::imagpart(cln::the(value))); - c.s << ")"; + // case 3, complex: x+y*I or x-y*I or -x+y*I or -x-y*I + if (precedence() <= level) + c.s << par_open; + print_real_number(c, r); + if (i < 0) { + if (i == -1) { + c.s << "-" << imag_sym; + } else { + print_real_number(c, i); + c.s << mul_sym << imag_sym; + } + } else { + if (i == 1) { + c.s << "+" << imag_sym; + } else { + c.s << "+"; + print_real_number(c, i); + c.s << mul_sym << imag_sym; + } + } + if (precedence() <= level) + c.s << par_close; } + } +} - } else if (is_a(c)) { +void numeric::do_print(const print_context & c, unsigned level) const +{ + print_numeric(c, "(", ")", "I", "*", level); +} - // C++ source output - std::ios::fmtflags oldflags = c.s.flags(); - c.s.setf(std::ios::scientific); - int oldprec = c.s.precision(); +void numeric::do_print_latex(const print_latex & c, unsigned level) const +{ + print_numeric(c, "{(", ")}", "i", " ", level); +} - // Set precision - if (is_a(c)) - c.s.precision(std::numeric_limits::digits10 + 1); - else - c.s.precision(std::numeric_limits::digits10 + 1); +void numeric::do_print_csrc(const print_csrc & c, unsigned level) const +{ + std::ios::fmtflags oldflags = c.s.flags(); + c.s.setf(std::ios::scientific); + int oldprec = c.s.precision(); - if (this->is_real()) { + // Set precision + if (is_a(c)) + c.s.precision(std::numeric_limits::digits10 + 1); + else + c.s.precision(std::numeric_limits::digits10 + 1); - // Real number - print_real_csrc(c, cln::the(value)); + if (this->is_real()) { - } else { + // Real number + print_real_csrc(c, cln::the(value)); - // Complex number - c.s << "std::complex<"; - if (is_a(c)) - c.s << "double>("; - else - c.s << "float>("; + } else { - print_real_csrc(c, cln::realpart(cln::the(value))); - c.s << ","; - print_real_csrc(c, cln::imagpart(cln::the(value))); - c.s << ")"; - } + // Complex number + c.s << "std::complex<"; + if (is_a(c)) + c.s << "double>("; + else + c.s << "float>("; + + print_real_csrc(c, cln::realpart(cln::the(value))); + c.s << ","; + print_real_csrc(c, cln::imagpart(cln::the(value))); + c.s << ")"; + } + + c.s.flags(oldflags); + c.s.precision(oldprec); +} - c.s.flags(oldflags); - c.s.precision(oldprec); +void numeric::do_print_csrc_cl_N(const print_csrc_cl_N & c, unsigned level) const +{ + if (this->is_real()) { + + // Real number + print_real_cl_N(c, cln::the(value)); } else { - const std::string par_open = is_a(c) ? "{(" : "("; - const std::string par_close = is_a(c) ? ")}" : ")"; - const std::string imag_sym = is_a(c) ? "i" : "I"; - const std::string mul_sym = is_a(c) ? " " : "*"; - const cln::cl_R r = cln::realpart(cln::the(value)); - const cln::cl_R i = cln::imagpart(cln::the(value)); - - if (is_a(c)) - c.s << class_name() << "('"; - if (cln::zerop(i)) { - // case 1, real: x or -x - if ((precedence() <= level) && (!this->is_nonneg_integer())) { - c.s << par_open; - print_real_number(c, r); - c.s << par_close; - } else { - print_real_number(c, r); - } - } else { - if (cln::zerop(r)) { - // case 2, imaginary: y*I or -y*I - 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; - } - 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 - if (precedence() <= level) - c.s << par_open; - print_real_number(c, r); - if (i < 0) { - if (i == -1) { - c.s << "-"+imag_sym; - } else { - print_real_number(c, i); - c.s << mul_sym+imag_sym; - } - } else { - if (i == 1) { - c.s << "+"+imag_sym; - } else { - c.s << "+"; - print_real_number(c, i); - c.s << mul_sym+imag_sym; - } - } - if (precedence() <= level) - c.s << par_close; - } - } - if (is_a(c)) - c.s << "')"; + // Complex number + c.s << "cln::complex("; + print_real_cl_N(c, cln::realpart(cln::the(value))); + c.s << ","; + print_real_cl_N(c, cln::imagpart(cln::the(value))); + c.s << ")"; } } +void numeric::do_print_tree(const print_tree & c, unsigned level) const +{ + c.s << std::string(level, ' ') << cln::the(value) + << " (" << class_name() << ")" << " @" << this + << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec + << std::endl; +} + +void numeric::do_print_python_repr(const print_python_repr & c, unsigned level) const +{ + c.s << class_name() << "('"; + print_numeric(c, "(", ")", "I", "*", level); + c.s << "')"; +} + bool numeric::info(unsigned inf) const { switch (inf) { @@ -1274,14 +1287,14 @@ const numeric exp(const numeric &x) /** Natural logarithm. * - * @param z complex number + * @param x complex number * @return arbitrary precision numerical log(x). * @exception pole_error("log(): logarithmic pole",0) */ -const numeric log(const numeric &z) +const numeric log(const numeric &x) { - if (z.is_zero()) + if (x.is_zero()) throw pole_error("log(): logarithmic pole",0); - return cln::log(z.to_cl_N()); + return cln::log(x.to_cl_N()); } @@ -1332,8 +1345,8 @@ const numeric acos(const numeric &x) /** Arcustangent. * - * @param z complex number - * @return atan(z) + * @param x complex number + * @return atan(x) * @exception pole_error("atan(): logarithmic pole",0) */ const numeric atan(const numeric &x) { @@ -1914,16 +1927,16 @@ const numeric lcm(const numeric &a, const numeric &b) /** Numeric square root. - * If possible, sqrt(z) should respect squares of exact numbers, i.e. sqrt(4) + * If possible, sqrt(x) should respect squares of exact numbers, i.e. sqrt(4) * should return integer 2. * - * @param z numeric argument - * @return square root of z. Branch cut along negative real axis, the negative - * real axis itself where imag(z)==0 and real(z)<0 belongs to the upper part - * where imag(z)>0. */ -const numeric sqrt(const numeric &z) + * @param x numeric argument + * @return square root of x. Branch cut along negative real axis, the negative + * real axis itself where imag(x)==0 and real(x)<0 belongs to the upper part + * where imag(x)>0. */ +const numeric sqrt(const numeric &x) { - return cln::sqrt(z.to_cl_N()); + return cln::sqrt(x.to_cl_N()); }