0

I have a situation where:

void foo( const double d )
{
    const double rounded_2_decimals = std::round(d*100.0) / 100.0;
    std::cout << "d=" << d << std::endl;
    std::cout << "r=" << rounded_2_decimals << std::endl;
}

When printed, d=3.125, but r=3.12 instead of r=3.13.

I suspect that is because the passed in d is actually 3.1249999.... This is why I put in the initial cout, so I could see the "true" value being passed in. Does std::cout round values before it displays them? How else could I see the "real" value being passed in?

T.C.
  • 133,968
  • 17
  • 288
  • 421
Stéphane
  • 19,459
  • 24
  • 95
  • 136
  • My bad, `round` always rounds away from zero. Use `std::setprecision`, or print as hexfloat. – T.C. Nov 06 '15 at 19:41
  • Isn't the definition of std::round() to round away from zero? Is there a way to change the "rounding mode"? – Stéphane Nov 06 '15 at 19:43
  • You're right (I misread the question as `foo(3.125)` printing 3.12), and then didn't lookup `std::round` because the only plausible explanation for that behavior is rounding half to even) – T.C. Nov 06 '15 at 19:45
  • Anyone know where it might be documented that std::cout rounds numbers before displaying them? I'd like to understand the exact rules. – Stéphane Nov 06 '15 at 20:47
  • Turns out my guess was right. When using `std::precision(25)` I noticed the number was indeed just a hair smaller than the .5 rounding limit: 3.1249999999999995559107901. – Stéphane Nov 06 '15 at 21:41

1 Answers1

2

Yes, std::cout does round values, however you can set a higher precision. First include the iomanip header. Then:

void foo( const double d )
{
    const double rounded_2_decimals = std::round(d*100.0) / 100.0;
    std::cout << "d=" << std::setprecision(9) <<  d << std::endl;
    std::cout << "r=" << std::setprecision(9) << rounded_2_decimals << std::endl;
}

Live example program here

ccoder83
  • 504
  • 6
  • 15
  • The trick was to use std::setprecision(9) in combination with std::fixed. – Stéphane Nov 06 '15 at 20:44
  • `std::fixed` isn't necessary to get the "real" value, as `std::precision` suffices in providing higher precision that specifies the max digits covering both sides of the decimal point. The result ignores trailing zeros that are less than the max digits specified. However, if you want specific formatting such as a fixed number of digits after the decimal point, or want to specify the precision for the number of digits after the decimal point, then yes, you can combine it with `std::fixed` – ccoder83 Nov 06 '15 at 21:32
  • Thanks, ccoder83. The truncation of the trailing zeros led me down the wrong path. Increasing the value in `std::setprecision()` eventually showed me what I suspected, that the value was just a hair smaller than the .5 necessary to round up. – Stéphane Nov 06 '15 at 21:44
  • @Stéphane it may take up to 53 digits to see the entire value if it's between 1.0 and 2.0, more if it's less than 1.0. – Mark Ransom Nov 06 '15 at 22:01