Marc Quebrar Tan
Marc Quebrar Tan

Reputation: 517

Setprecision is Confusing

I just want to ask about setprecision because I'm a bit confused.

here's the code:

#include <iostream>
#include <iomanip>
using namespace std;

int main()

{
  double rate = x;
  cout << fixed << setprecision(2) << rate;
}

where x = to following:

the left side of equation are the values of x.

1.105 = 1.10 should be 1.11

1.115 = 1.11 should be 1.12

1.125 = 1.12 should be 1.13

1.135 = 1.14 which is correct

1.145 = 1.15 also correct

but if x is:

2.115 = 2.12 which is correct

2.125 = 2.12 should be 2.13

so why in a certain value it's correct but sometimes it's wrong?

please enlighten me. thanks

Upvotes: 12

Views: 21912

Answers (3)

Mark B
Mark B

Reputation: 96241

Some of the numbers you're printing may not be representable as a floating point number and may actually be lower or higher than you think, directly affecting the rounding.

Since you're trying to format a floating point number to fixed point, have you considered actually USING a fixed point number (int/long scaled by say 1000 depending on your needs) that has its own insert operator defined? Then you'll always get accurate display and rounding without needing to rely on setprecision having any particular behavior (I couldn't find the relevant conversion section in the standard in a quick look).

Upvotes: 2

James Kanze
James Kanze

Reputation: 153909

Why do you say that 1.105 should be 1.11? The C++ standard says nothing about it, but the default rounding mode on most of the usual machines (Intel, Sparc, etc.) is round to even, so 1.105 should be 1.10. In general, when the exact result is exactly between two representable values, the rule is to round to the one with an even least significant digit.

I also wonder where you're getting these values. On the usual machines, 1.105 can't be represented, so you have something slightly larger or slightly smaller.

And of course, the above comments apply for all of the other values you've cited.

Upvotes: 1

NPE
NPE

Reputation: 500267

There is no reason to expect that any of the constants in your post can be represented exactly using the floating-point system. As a consequence, the exact halves that you have may no longer be exact halves once you store them in a double variable (regardless of how the iostreams are meant to round such numbers.)

The following code illustrates my point:

#include <iostream>
#include <iomanip>

using namespace std;

int main()

{
  double rate = 1.115;
  cout << fixed << setprecision(20) << rate;
}

Output:

1.11499999999999999112

I would recommend taking a look at the FAQ.

Upvotes: 8

Related Questions