19

Maybe, it's very simple question but I couldn't get the answer. I've been searching quite a while ( now Google think that I'm sending automated queries http://twitter.com/michaelsync/status/17177278608 ) ..

int n = 4.35 *100;
cout << n;

Why does the output become "434" instead of "435"? 4.35 * 100 = 435 which is a integer value and this should be assignable to the integer variable "n", right?

OR Does the C++ compiler cast 4.35 to integer before multiplying? I think it won't. Why does the compiler automatically change 4.35 to 4.34 which is still a float??

Thanks.

Michael Sync
  • 4,834
  • 10
  • 40
  • 58
  • 3
    How would the result be 434 if 4.35 is cast to an `int` before multiplication? Wouldn't that be 400? Just to rule out one of your explanations. – pmr Jun 27 '10 at 16:27
  • if you did `int y = (int) (4.35 * 100);` you wouldn't - if you're going to call a function, you can pick and choose an appropriate one to get the answer you need, which you could also do in C++. But in the example code you're not calling a function, you're using the implicit typecasting provided by the language. – Nick Bastin Jun 27 '10 at 16:39
  • 2
    4.35 is not exactly representable. The next closest double value seems to be (in your case) 4.34999... which, multiplied with 100, results in 434.999... and is therefore converted to 434. – sellibitze Jun 27 '10 at 17:39

5 Answers5

41

What Every Computer Scientist Should Know About Floating-Point Arithmetic

That's really just a starting point, sadly, as then languages introduce their own foibles as to when they do type conversions, etc. In this case you've merely created a situation where the constant 4.35 can't be represented precisely, and thus 4.35*100 is more like 434.9999999999, and the cast to int does trunc, not round.

Gyuri
  • 4,548
  • 4
  • 34
  • 44
Nick Bastin
  • 30,415
  • 7
  • 59
  • 78
  • Is it only in C++? It doesn't happen in C#.. int n = Convert.ToInt32(4.35 * 100); Console.WriteLine(n); – Michael Sync Jun 27 '10 at 16:34
  • It does happen in C# if you cast, but you're not casting - ToInt32 rounds (as it very clearly states in the documentation). You could round in C++ as well (well, `floor` or `ceil` but add/subtract 0.5 to make that a rounding function) – Nick Bastin Jun 27 '10 at 16:36
7

If you run this statement:

cout << 4.35

Dollars to donuts you get something approximately like 4.3499998821 because 4.35 isn't exactly representable in a float.

When the compiler casts a float to an int it truncates.

To get the behavior your expect, try:

int n = floor((4.35 * 100.0) + 0.5);

(The trickyness with floor is because C++ doesn't have a native round() function)

Donnie
  • 45,732
  • 10
  • 64
  • 86
2

The internal representation of 4.35 ends up being 4.349999999 or similar. Multiplying by 100 shifts the decimal, and the .9999 is dropped off (truncated) when converting to int.

Edit: Was looking for the link Nick posted. :)

Cogwheel
  • 22,781
  • 4
  • 49
  • 67
0

Floating point numbers don't work that way. Many (most, technically an infinite number of...) values cannot be stored or manipulated precisely as floating point. 4.35 would seem to be one of them. It's getting stored as something that's actually below 4.35, hence your result.

Community
  • 1
  • 1
Nicholas Knight
  • 15,774
  • 5
  • 45
  • 57
0

When a float is converted to an int the fractional part is truncated, the conversion doesn't take the nearest int to the float in value.

4.35 can't be exactly represented as a float, the nearest representable number is (we can deduce) very slightly less that 4.35, i.e. 4.34999... , so when multiplied by 100 you get 434.999...

If you want to convert a positive float to the nearest int you should add 0.5 before converting to int.

E.g.

int n = (4.35 * 100) + 0.5;
cout << n;
CB Bailey
  • 755,051
  • 104
  • 632
  • 656