2

I was of the opinion that setprecision doesnt change the value in variable itself. Also, when you attach setprecision to cout, it sticks with it only once. However, when I run code to verify, it doesnt work.

Consider the following code snippet:

int main()
{
    double x = 9.87654321;
    cout << setprecision(3) << fixed << x <<endl;    //Returns 9.877 as it should
    cout << x << endl;                               //Returns truncated value 9.877 again though it shouldnt.

    return 0;
}   

Interesting part is, if we replace cout << x << endl; by a line setting precision to say 7, then it DOES display the correct value. Can anyone please explain this phenomenon?

James
  • 5,355
  • 2
  • 18
  • 30
Scranton
  • 21
  • 2
  • Possibly related: http://stackoverflow.com/questions/1532640/which-iomanip-manipulators-are-sticky/1533752#1533752 – CB Bailey Feb 11 '11 at 17:59

3 Answers3

5

You don't reset the precision to the original value so it's just using 3 as the precision value for both output operations.

If you want to restore the original precision then you need to save it. The initial value for standard ostreams is 6 which may not be accurate enough for many purposes.

int main()
{
    double x = 9.87654321;

    size_t save_prec = cout.precision();
    cout << setprecision(3) << fixed << x <<endl;
    cout.precision(save_prec);

    cout << x << endl;

    return 0;
}
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
0

It sets the precision of the output stream, not x, meaning after the call to setprecision(3), cout outputs all numbers with precision of 3.

http://www.cplusplus.com/reference/iostream/manipulators/setprecision/

Try this, which will show that x has not changed.

int main() 
{     
  double x = 9.87654321;     
  cout << setprecision(3) << fixed << x <<endl;    //Returns 9.877 as it should     
  cerr << x << endl;                               //Returns 9.87654 to stderr  
  return 0; 
} 
James
  • 5,355
  • 2
  • 18
  • 30
  • So in that case, If I do something like y=x, after setting precision to 3 and then print y, it should print the complete value? But then I tried it and it doesnt! – Scranton Feb 11 '11 at 17:49
  • Horrible fix. `cout` and `cerr` are completely different streams and have different purposes -- just because they sometimes map to the same output doesn't mean they're interchangeable. – John Bartholomew Feb 11 '11 at 17:50
  • @John: not a fix, just an example. I wasn't implying they were the same. – James Feb 11 '11 at 17:50
  • @Scranton: That's because you are probably still using `cout`, which still has a precision of 3 after the call to `setprecision`. – James Feb 11 '11 at 17:51
  • @James: Sorry, slight misunderstanding on my part -- although I still think it's somewhat misleading. – John Bartholomew Feb 11 '11 at 17:52
  • Does this mean, that if you use setprecision once, it sticks to all cout usages you make in the future? I was of the misinformed opinion that setprecision doesnt stick to cout unless you specify it every single time. – Scranton Feb 11 '11 at 17:53
  • @Scranton: You may be thinking of `width()`. Most formatted output functions automatically reset the `width()` to 0. No other formatting flags are reset by the usual formatted output functions. – CB Bailey Feb 11 '11 at 17:57
0

Other answers have indicated the problem. One possible solution is to use the Boost I/O Stream state saver library to do the work of saving the I/O stream formatting state and restoring it at the appropriate time.

John Bartholomew
  • 6,428
  • 1
  • 30
  • 39