0

Let us say I have

float val = 99999.9;

When I do this:

int val2 = val*100;

val2 is equal to 9999989 in Visual Studio 2010.

However, if I do the same with other compilers (like GCC for example), the result would be val2 = 9999990.

How to explain such a difference ?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
LudoDu31
  • 31
  • 4
  • 1
    Hint 1: `float` is **floating** point and can't represent every real number exactly. See https://stackoverflow.com/questions/588004/is-floating-point-math-broken. Hint 2: casting to `int` always rounds down. – Nate Eldredge Apr 01 '20 at 01:26
  • It looks like here int does not round down val2, because val2 is 9999989 in Visual Studio. – LudoDu31 Apr 01 '20 at 01:34
  • No, it **does** round down, always (for positive values). So this indicates that Visual Studio is representing `99999.9` by a value that is slightly **less** than `99999.9`, whereas gcc is representing it by a value that is slightly **greater**. – Nate Eldredge Apr 01 '20 at 01:37
  • The point is that you need to write your code in such a way that it works correctly no matter which way the compiler chooses to represent the number. As such, a straight cast to `int` is generally the wrong way to "convert" a floating point number to an integer. – Nate Eldredge Apr 01 '20 at 01:39
  • Ok, so what do you suggest for me to have always val2 = 9999990, whatever the compiler is ? – LudoDu31 Apr 01 '20 at 01:43
  • @LudoDu31 A 'cheap' (but not always accurate) way to get a *rounding* to the nearest integer is to add 0.5 to the floating-point value before converting to an integer. Something like: `int val2 = val * 100 + 0.5;` would work in most cases. – Adrian Mole Apr 01 '20 at 01:47
  • Thanks Adrian, yes it looks working that way. However I am not sure to be able to demonstrate why – LudoDu31 Apr 01 '20 at 01:59
  • 2
    the reason is because C allows the value with a higher precision internally so on some compilers it's done in the 80-bit extended precision and some it's in SSE 32-bit single precision. There are lots of similar issues [Difference in floating point arithmetics between x86 and x64](https://stackoverflow.com/q/22710272/995714), [Do FP operations give EXACTLY the same result on various x86 CPUs?](https://stackoverflow.com/q/13102167/995714), [acos(double) gives different result on x64 and x32 Visual Studio](https://stackoverflow.com/q/45734549/995714) – phuclv Apr 01 '20 at 02:35
  • @phuclv: That alone does not explain it. Both the C and C++ standards require the implementation to discard excess precision in assignments and casts. So, after `float val = 99999.9;`, `val` must be some value representable in `float`. For this particular numeral, whether it is treated as an IEEE-754 binary32 or binary64 or an Intel 80-bit floating-point value, the result would be 9999990. Microsoft must be doing something other than what the standard says. – Eric Postpischil Apr 03 '20 at 02:27
  • Please edit the question to provide a [mre]. – Eric Postpischil Apr 03 '20 at 02:27

0 Answers0