2

Why is it that when I run the C code

float x = 4.2 int y = 0 y = x*100 printf("%i\n", y); 

I get 419 back? Shouldn't it be 420? This has me stumped.

2
  • 2
    Typical floating point precision issue. If x*100 comes out as 419.999981, assigning it to y truncates it to 419. Commented Mar 27, 2014 at 2:15
  • 1
    Study en.wikipedia.org/wiki/Floating_point Commented Mar 27, 2014 at 2:17

4 Answers 4

3

To illustrate, look at the intermediate values:

int main() { float x = 4.2; int y; printf("x = %f\n", x); printf("x * 100 = %f\n", x * 100); y = x * 100; printf("y = %i\n", y); return 0; } x = 4.200000 // Original x x * 100 = 419.999981 // Floating point multiplication precision y = 419 // Assign to int truncates 

Per @Lutzi's excellent suggestion, this is more clearly illustrated if we print all the float values with precision that is higher than they represent:

... printf("x = %.20f\n", x); printf("x * 100 = %.20f\n", x * 100); ... 

And then you can see that the value assigned to x isn't perfectly precise to start with:

x = 4.19999980926513671875 x * 100 = 419.99998092651367187500 y = 419 
Sign up to request clarification or add additional context in comments.

1 Comment

You can use insanely high precision in the output to better demonstrate your point, something like "x = %.36f\n".
1

A floating point number is stored as an approximate value - not the exact floating point value. It has a representation due to which the result gets truncated when you convert it into an integer. You can see more information about the representation here.

This is an example representation of a single precision floating point number :

enter image description here

Comments

0

float isn't large enough to store 4.2 precisely. If you print x with enough precision you'll probably see it come out as 4.19999995 or so. Multiplying by 100 yields 419.999995 and the integer assignment truncates (rounds down). It should work if you make x a double.

2 Comments

A double cannot represent 4.2 exactly any more than a float can. It may work by “luck” with a double type if the double nearest to 4.2 is above 4.2 instead of being below it, but without looking, it is in first approximation a 50-50 chance.
More precisely, the decimal representation of the stored value for 4.2 is 4.19999980926513671875. And yes, your guess is right, in double precision, the stored value representing 4.2is 4.20000000000000017763568394002504646778106689453125.
0

4.2 is not in the finite number space of a float, so the system uses the closest possible approximation, which is slightly below 4.2. If you now multiply this with 100 (which is an exact float), you get 419.99something. printf()ing this with %i performs not rounding, but truncation - so you get 419.

2 Comments

The “printf()ing this with %i performs not rounding, but truncation” part of this answer is wrong. The function printf is variadic. It performs no conversion on its arguments after the first one. The assignment y= converts 419.99something into 419. Passing a floating-point number to printf("%i would be undefined behavior.
@PascalCuoq - That is exactly what I was saying: you take 419.99something and printf('%i') it ... which ofcourse implies a cast. English is not my first language, but I would have thought that to be unambitious

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.