Convert float to int implicit vs explicit (excellent) mismatch

int i1 = 0, i2 = 0; float f = 2.8f; i1 += f; i2 += (int)f; f += 0.1; i1 += f; i2 += (int)f; f += 0.1; i1 += f; i2 += (int)f; printf("%d %d\n", i1, i2); 

Output:

 7 6 
  • Why will the implicit and explicit conversion results be different?
  • I would like the results to be similar to those that were for implicit conversion, but without compilation warning. Is it possible?

The platform is Windows7, VS2010 or 2013.

+6
source share
3 answers

To analyze this, the first task is to rewrite a += b as a = a + b .

i + (int)f will be calculated in integer arithmetic due to an explicit cast.

But i + f will be calculated in floating point arithmetic due to type advancement.

Thus, expressions have different types. Due to how the floating point works, the result when converting back to int may be different.

The moral of this story is not to use += for mixed types and not to ignore useful compiler warnings.

+10
source

Below is a more detailed analysis of the situation, in the form of code generated by the compiler and the values โ€‹โ€‹of the variables (i1, i2 and f) after each operation.

 1. int i1 = 0, i2 = 0; 2. float f = 2.8f; 3. i1 += f; //i1 = (int)((float) i1 + f); | i1 => 2, i2 => 0, f => 2.8 4. i2 += (int) f; //i2 = i2 + (int) f; | i1 => 2, i2 => 2, f => 2.8 5. f += 0.1; // | i1 => 2, i2 => 2, f => 2.9 6. i1 += f; //i1 = (int)((float) i1 + f); | i1 => 4, i2 => 2, f => 2.9 7. i2 += (int) f; //i2 = i2 + (int) f; | i1 => 4, i2 => 4, f => 2.9 8. f += 0.1; // | i1 => 4, i2 => 4, f => 3.0 9. i1 += f; //i1 = (int)((float) i1 + f); | i1 => 7, i2 => 4, f => 3.0 10. i2 += (int) f; //i2 = i2 + (int) f; | i1 => 7, i2 => 6, f => 3.0 11. printf("%d %d", i1, i2); 

Pay attention to lines 3, 6 and 9, here i1 is converted to float due to the type of advancement (I would recommend you read this wiki), and then the result is converted back to an integer to assign an integer L-value.

Lines 5 and 8 will prompt this warning, which can be easily eliminated by converting 'f + = 0.1;' k 'f + = 0,1f;'

warning C4305: '+ =': truncation from 'double' to 'float'

+5
source

Since your explicit conversions are done before , add ( float f to int ). Implicit conversions:

  • Convert i1 to float .
  • Convert result to int after .
+4
source

All Articles