views:

528

answers:

7

Why does this:

int main(void)
{
    short w = 30;
    return  1.2 * w;
}

return 35?

+12  A: 

1.2 * w is 36.0. It has the double type meaning it is not represented exactly.

Likely it turns out to be slightly less than 36, maybe 35.99999 so when you return it the fractional part is discarded and the integer part only is returned. That's how you get 35.


P.S. All operations with floating point are not precise. You should expect little discrepancies. Also when you compare a floating point value against a fixed value, you mustn't do a direct comparison but do a range comparison.

Wrong: if (value == 36.0) { /* ... */ }

Correct: if (abs (value - 36.0) < 0.0001) { /* ... */ }

Developer Art
Spot on I reckon. If the function returned a double then we'd know for sure.
ChrisBD
Note that `36.0` *can* be represented exactly in floating point - but `1.2` cannot.
caf
@Developer Art: there is no imprecision in the operation going on here. The problem is that there is no such floating point value as 1.2. It's rounded before it even gets compiled.
R..
*"All operations with floating point are not precise"* is wrong. The modulo operation in IEEE 754-1985 is exact. Addition, subtraction, multiplication and even sometimes division are exact if you provide suitable arguments. For example `0.5 + 0.5 == 1.0` will hold true in any binary floating-point model with at least 2 bits of precision. So will `12.0 / 3.0` or `0.875 * 0.5`.
Roland Illig
+3  A: 

It's an issue with binary floating point precision. 1.2 is very slightly less than 1.2, so the result of the multiplication is slightly less than 36.

0xA3
A: 

Don't expect absolutely exact result in floating point operations. Multiplication result may be, for example, 35.9999, which is rounded to 35.

Alex Farber
+2  A: 

Because of representation: 1.2 is really something like 1.1999999

Mitch Wheat
+14  A: 

If you want to get more suitable result, try the following:

return 12*w/10
ecik
Good answer! +1
leppie
Keep in mind that the multiplication could overflow even if the final result would fit in an `int`. Using floating point (`12.0*w/10.0`) could fix this problem.
R..
A: 

short w = 30; return 1.2 * w;

In return statement first sort value is type cast in double because 1.2 is double type so it will multiply 1.2 * 30.000000 and result become around 35.999999 and function return type is int so decimal part is truncate and it return 35 only.

Anand Kumar
+2  A: 

Since floating point math could be inexact, use round() before casting to integer, to get a better result.

#include <math.h>
...
return (int)round(some_real_value);
Frayser