Reputation: 517
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
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
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
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