From 2960d2b85f1bea56167edf45ae6cb072e7d95299 Mon Sep 17 00:00:00 2001 From: Christian Bauer Date: Wed, 5 Feb 2003 22:47:12 +0000 Subject: [PATCH] synced to 1.0 --- doc/tutorial/ginac.texi | 6 +- ginac/numeric.cpp | 152 ++++++++++++++++++++++++++++++++-------- ginac/print.h | 4 +- 3 files changed, 126 insertions(+), 36 deletions(-) diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index dd89e5fa..40adeff0 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -4336,9 +4336,9 @@ numbers are written. The above example will produce (note the @code{x^2} being converted to @code{x*x}): @example -float f = (3.000000e+00/2.000000e+00)*(x*x)+4.500000e+00; -double d = (3.000000e+00/2.000000e+00)*(x*x)+4.500000e+00; -cl_N n = (cln::cl_F("3.0")/cln::cl_F("2.0"))*(x*x)+cln::cl_F("4.5"); +float f = (3.0/2.0)*(x*x)+4.500000e+00; +double d = (3.0/2.0)*(x*x)+4.5000000000000000e+00; +cl_N n = cln::cl_RA("3/2")*(x*x)+cln::cl_F("4.5_17"); @end example The @code{print_context} type @code{print_tree} provides a dump of the diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index 5c8f6506..3ca0389d 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include "numeric.h" #include "ex.h" @@ -314,7 +315,7 @@ DEFAULT_UNARCHIVE(numeric) * want to visibly distinguish from cl_LF. * * @see numeric::print() */ -static void print_real_number(const print_context & c, const cln::cl_R &x) +static void print_real_number(const print_context & c, const cln::cl_R & x) { cln::cl_print_flags ourflags; if (cln::instanceof(x, cln::cl_RA_ring)) { @@ -340,6 +341,82 @@ static void print_real_number(const print_context & c, const cln::cl_R &x) } } +/** Helper function to print integer number in C++ source format. + * + * @see numeric::print() */ +static void print_integer_csrc(const print_context & c, const cln::cl_I & x) +{ + // Print small numbers in compact float format, but larger numbers in + // scientific format + const int max_cln_int = 536870911; // 2^29-1 + if (x >= cln::cl_I(-max_cln_int) && x <= cln::cl_I(max_cln_int)) + c.s << cln::cl_I_to_int(x) << ".0"; + else + c.s << cln::double_approx(x); +} + +/** Helper function to print real number in C++ source format. + * + * @see numeric::print() */ +static void print_real_csrc(const print_context & c, const cln::cl_R & x) +{ + if (cln::instanceof(x, cln::cl_I_ring)) { + + // Integer number + print_integer_csrc(c, cln::the(x)); + + } else if (cln::instanceof(x, cln::cl_RA_ring)) { + + // Rational number + const cln::cl_I numer = cln::numerator(cln::the(x)); + const cln::cl_I denom = cln::denominator(cln::the(x)); + if (cln::plusp(x) > 0) { + c.s << "("; + print_integer_csrc(c, numer); + } else { + c.s << "-("; + print_integer_csrc(c, -numer); + } + c.s << "/"; + print_integer_csrc(c, denom); + c.s << ")"; + + } else { + + // Anything else + c.s << cln::double_approx(x); + } +} + +/** Helper function to print real number in C++ source format using cl_N types. + * + * @see numeric::print() */ +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 << "\")"; + + } else if (cln::instanceof(x, cln::cl_RA_ring)) { + + // Rational number + cln::cl_print_flags ourflags; + c.s << "cln::cl_RA(\""; + cln::print_rational(c.s, ourflags, cln::the(x)); + c.s << "\")"; + + } else { + + // Anything else + c.s << "cln::cl_F(\""; + print_real_number(c, cln::cl_float(1.0, cln::default_float_format) * x); + c.s << "_" << Digits << "\")"; + } +} + /** This method adds to the output so it blends more consistently together * with the other routines and produces something compatible to ginsh input. * @@ -353,56 +430,69 @@ void numeric::print(const print_context & c, unsigned level) const << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec << std::endl; + } else if (is_a(c)) { + + // CLN output + if (this->is_real()) { + + // Real number + print_real_cl_N(c, cln::the(value)); + + } 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 << ")"; + } + } else if (is_a(c)) { + // C++ source output std::ios::fmtflags oldflags = c.s.flags(); c.s.setf(std::ios::scientific); int oldprec = c.s.precision(); + + // Set precision if (is_a(c)) - c.s.precision(16); + c.s.precision(std::numeric_limits::digits10 + 1); else - c.s.precision(7); - if (is_a(c) && this->is_integer()) { - c.s << "cln::cl_I(\""; - const cln::cl_R r = cln::realpart(cln::the(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(c)) - c.s << "cln::cl_F(\"" << numer().evalf() << "\")"; - else - c.s << numer().to_double(); - } else { - c.s << "-("; - if (is_a(c)) - c.s << "cln::cl_F(\"" << -numer().evalf() << "\")"; - else - c.s << -numer().to_double(); - } - c.s << "/"; - if (is_a(c)) - c.s << "cln::cl_F(\"" << denom().evalf() << "\")"; - else - c.s << denom().to_double(); - c.s << ")"; + c.s.precision(std::numeric_limits::digits10 + 1); + + if (this->is_real()) { + + // Real number + print_real_csrc(c, cln::the(value)); + } else { - if (is_a(c)) - c.s << "cln::cl_F(\"" << evalf() << "_" << Digits << "\")"; + + // Complex number + c.s << "std::complex<"; + if (is_a(c)) + c.s << "double>("; else - c.s << to_double(); + 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); } 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)) { diff --git a/ginac/print.h b/ginac/print.h index 4010d38d..d7230928 100644 --- a/ginac/print.h +++ b/ginac/print.h @@ -83,7 +83,7 @@ public: print_csrc(std::ostream &, unsigned options = 0); }; -/** Context for C source output using float numbers. */ +/** Context for C source output using float precision. */ class print_csrc_float : public print_csrc { public: @@ -91,7 +91,7 @@ public: print_csrc_float(std::ostream &, unsigned options = 0); }; -/** Context for C source output using double numbers. */ +/** Context for C source output using double precision. */ class print_csrc_double : public print_csrc { public: -- 2.47.0