2
double value;
std::ostringstream s;
s << std::fixed << std::setprecision(3) << value;

When value wanders in the range -1.0e-14 to 1.0e-14, s flickers between "0.000" and "-0.000". Is there a clean way to suppress the minus sign, which only indicates irrelevant noise ten decimal places farther down?

(The less general case is cout << ....)

what is the best way to avoid negative zero in output? addresses superficial issues. Its answer, rounding to the right number of significant digits before passing to <<, is a lot of computation compared to "just drop the frickin' minus if all digits are zero."

Community
  • 1
  • 1
Camille Goudeseune
  • 2,934
  • 2
  • 35
  • 56
  • It might get a bit better with either [`setw`](http://en.cppreference.com/w/cpp/io/manip/setw) (right-align the output) or [`showpos`](http://en.cppreference.com/w/cpp/io/manip/showpos) (show either `+` or `-`). – dyp Jan 26 '14 at 23:10
  • Yes, `showpos` flickers + and - instead of space and minus. About one pixel less flicker :-). – Camille Goudeseune Jan 26 '14 at 23:20
  • Is there anything particularly wrong with `return (s.str() == "-0.000") ? string("0.000") : s.str();`? Or does that amount to admitting defeat? In the `cout` case you'd have to do `cout << fixmydouble(value);`. – Steve Jessop Jan 26 '14 at 23:22
  • @SteveJessop If you have a serious illness do you want the doctors only to give you pain killers? – Sebastian Hoffmann Jan 26 '14 at 23:24
  • @Paranaix: ah, of course. The question doesn't *explicitly* state that someone will die if this particular feature isn't done for us by the C++ standard libraries, but I see now that's a quite reasonable assumption to make. If I'm lying around in bed moaning about a broken fingernail, then I probably benefit from the doctor telling me to get over it and move on with my life ;-p I want to see if the baseline "ugly" solution is as easy as I thought, or if there were further concerns (e.g wanting to read the format settings from the stream rather than just "knowing" them) – Steve Jessop Jan 26 '14 at 23:26
  • Yes, an explicit test for "0.000" amounts to admitting defeat, because it uses knowledge of the stream's format, just like rounding beforehand does (and maybe with even more computation). But, as the saying goes, sometimes the dragon wins... – Camille Goudeseune Jan 27 '14 at 15:13

1 Answers1

1

Even if nothing in <iomanip> can adjust the actual stream, we can at least not depend on the value passed to setprecision(), like this:

const std::string& t = s.str();
return t.find_first_of("123456789") == t.npos && t[0] == '-' ?
  t.substr(1) : t;

If no digits from 1..9 are found, then all digits must be 0.

If, furthermore, it starts with minus, then skip that character.

Camille Goudeseune
  • 2,934
  • 2
  • 35
  • 56