3

Would anyone be able to explain why int and const int give different results when cast to float and used in floating point math? See for example this piece of code:

int _tmain(int argc, _TCHAR* argv[])
{
      int x = 1000;
      const int y = 1000;
      float fx = (float) x;
      float fy = (float) y;

      printf("(int = 1000) * 0.3f = %4.10f \n", 0.3f*x); 
      printf("(const int = 1000) * 0.3f = %4.10f \n", 0.3f*y);
      printf("(float)(int = 1000) * 0.3f = %4.10f \n", 0.3f*fx); 
      printf("(float)(const int = 1000) * 0.3f = %4.10f \n", 0.3f*fy);
      return 0;
}

The result is:

(int = 1000) * 0.3f = 300.0000119209
(const int = 1000) * 0.3f = 300.0000000000
(float)(int = 1000) * 0.3f = 300.0000119209
(float)(const int = 1000) * 0.3f = 300.0000119209

My guess is that in the first case 0.3f*(int) is implicitly cast to a float, whereas in the second case 0.3f*(const int) is implicitly cast to a double. Is this correct, and if so why does this happen? Also, what is the "right" approach?

Many thanks

aschepler
  • 70,891
  • 9
  • 107
  • 161

1 Answers1

2

The multiplication of two constants can be performed by the compiler before the code is even generated. The rest must be done at run-time.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Hi Mark, thank you for the reply. Why would the multiplication give different results when performed by the compiler and executed at run-time? – user2478419 Jun 12 '13 at 13:28
  • My guess would be that the compiler does all floating point math at double precision even if the final result is a float. – Lee Daniel Crocker Jun 12 '13 at 13:41
  • 2
    @LeeDanielCrocker: It is likely the other way around; the compiler likely evaluates `.3f * y` using `float`, as this produces exactly 300. Evaluating `.3f * y` by converting `.3f` and `y` to `double` produces the other value, near 300.0000119209. You could get 300 by treating `.3f` as a `double` constant (completely ignoring the `f`, so it is never converted to `float` at all), then multiplying by 1000, but that would be a bigger flaw in the compiler. Then the other three expressions are evaluated using `double` or greater, after `.3f` is converted to `float`. – Eric Postpischil Jun 12 '13 at 16:34