Mercurial > octave
changeset 27473:d503426130bf
Display '*' rather than '0' for small rational approximations (bug #56941)
* pr-output.cc (operator << (pr_rational_float)): New boolean variable
have_neg_sign to track whether extra character is required in output string to
acount for negative sign. Call rational_approx with full width argument for
negative numbers and width-1 for positive numbers. Change output to '*'
if return value from rational_approx is '0' (which only indicates small).
For large integers which aren't in rational approximation format of N/D (no
'/') character, use a smaller field width.
* oct-string.cc (rational_approx): Change variable name "buf2" to "init_buf"
for clarity. Reformat "else if (condition)" to "else { if (condition) }" for
readability. Expand comments and correct typos.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 04 Oct 2019 13:51:47 -0700 |
parents | c0883bfc0f36 |
children | 3fec8e9fa2aa |
files | libinterp/corefcn/pr-output.cc liboctave/util/oct-string.cc |
diffstat | 2 files changed, 43 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/pr-output.cc Fri Oct 04 14:13:06 2019 -0400 +++ b/libinterp/corefcn/pr-output.cc Fri Oct 04 13:51:47 2019 -0700 @@ -240,19 +240,46 @@ octave::preserve_stream_state stream_state (os); float_format real_fmt = prf.m_ff; + bool have_neg_sign = prf.m_val < 0; int fw = (rat_string_len > 0 ? rat_string_len : real_fmt.width ()); - std::string s = rational_approx (prf.m_val, fw); + std::string s; + + if (have_neg_sign) + s = rational_approx (prf.m_val, fw); + else + s = rational_approx (prf.m_val, fw-1); if (fw >= 0) os << std::setw (fw); os.flags (real_fmt.format_flags ()); - if (fw > 0 && s.length () > static_cast<unsigned int> (fw)) - os << '*'; - else - os << s; + if (s == "0") + s = '*'; + else if (fw > 0) + { + if (s.find ('/') != std::string::npos) + { + if (s.length () > (static_cast<unsigned int> (fw))) + s = '*'; + } + else + { + if (have_neg_sign) + { + if (s.length () > (static_cast<unsigned int> (fw) - 2)) + s = '*'; + } + else + { + if (s.length () > (static_cast<unsigned int> (fw) - 3)) + s = '*'; + } + } + } + + os << s; return os; }
--- a/liboctave/util/oct-string.cc Fri Oct 04 14:13:06 2019 -0400 +++ b/liboctave/util/oct-string.cc Fri Oct 04 13:51:47 2019 -0700 @@ -586,10 +586,10 @@ T frac = val - n; int m = 0; - std::ostringstream buf2; - buf2.flags (std::ios::fixed); - buf2 << std::setprecision (0) << static_cast<int> (n); - s = buf2.str (); + std::ostringstream init_buf; + init_buf.flags (std::ios::fixed); + init_buf << std::setprecision (0) << static_cast<int> (n); + s = init_buf.str (); while (true) { @@ -624,8 +624,11 @@ if (buf.str ().length () > static_cast<unsigned int> (len + 2)) break; } - else if (buf.str ().length () > static_cast<unsigned int> (len)) - break; + else + { + if (buf.str ().length () > static_cast<unsigned int> (len)) + break; + } if (std::abs (n) > std::numeric_limits<int>::max () || std::abs (d) > std::numeric_limits<int>::max ()) @@ -636,7 +639,7 @@ if (lastd < 0) { - // Move sign to the top + // Move negative sign from denominator to numerator lastd = - lastd; lastn = - lastn; std::ostringstream buf; @@ -650,6 +653,6 @@ return s; } -// instanciate the template for float and double +// instantiate the template for float and double template std::string rational_approx <float> (float val, int len); template std::string rational_approx <double> (double val, int len);