问题
While trying to figure out how to round a float like 1.255
to the nearest hundredth, I found something interesting. I'm using gcc 4.4.5 on Debian 6.
int x = (1.255 * 100) + 0.5; // gives me back 125 instead of 126.
float y = (1.255 * 100) + 0.5; // gives me back 126.000000.
Why is is that when I save to an int
I get back 125
and not 126
? In fedora when I save the above expression to an int
I get back 126
. Is this a gcc bug in debian ? Any help would be greatly appreciated.
Thanks.
回答1:
Although this looks like a "typical" floating-point question, it's more complicated than that.
This one involves a combination of 3 things:
- The "usual" floating-point representation stuff.
- Implicit casting.
- Implicit type-promotion.
Let's break this down:
Floating-point literals are of type double
by default. Hence 1.255
is of type double
.
Thus the expression:
(1.255 * 100) + 0.5
is done using type double
.
But because binary floating-point can't represent 1.255
exactly, the expression evaluates to:
(1.255 * 100) + 0.5 = 125.99999999999999000000
and is of type double
.
Since this is less than 126
, storing it to an integer will result in 125
.
Storing it to float
will round it to the nearest float
, which results in 126
.
int x = (1.255 * 100.) + 0.5;
float y = (1.255 * 100.) + 0.5;
double z = (1.255 * 100.) + 0.5;
cout << fixed;
cout << x << endl;
cout << setprecision(20) << y << endl;
cout << setprecision(20) << z << endl;
Output:
125
126.00000000000000000000
125.99999999999999000000
来源:https://stackoverflow.com/questions/9694325/having-trouble-rounding-in-c