将float转换为int隐式vs显式(强制转换)差异

时间:2016-03-15 16:28:14

标签: c casting floating-point

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);

输出:

7 6
  1. 为什么隐式和显式转换结果会有所不同?
  2. 我希望结果类似于隐式转换,但没有编译警告。有可能吗?
  3. 平台是Windows7,VS2010或2013。

3 个答案:

答案 0 :(得分:10)

要分析这一点,第一项工作是将a += b重写为a = a + b

由于显式转换,

i + (int)f将以整数算术计算。

但由于类型提升,将在浮点运算中计算i + f

所以表达式有不同的类型。由于浮点的工作方式,结果转换回int 会有所不同。

故事的寓意是使用+=用于混合类型,并且不要忽略有用的编译器警告。

答案 1 :(得分:5)

这是更详细的情况分解,以编译器生成的代码和变量值(i1,i2和f)的形式逐行执行。

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);

注意第3,6和9行,这里i1由于type promotion而转换为float(我建议你阅读这个wiki),然后将结果转换回整数以赋给整数L-值。

第5行和第8行会提示此警告,可以通过转换'f + = 0.1;'来轻松修复到'f + = 0.1f;'

  

警告C4305:'+ =':从'double'截断到'float'

答案 2 :(得分:4)

因为您的显式转化是之前添加(spring.data.mongodb.host=localhost spring.data.mongodb.password= spring.data.mongodb.port=27017 spring.data.mongodb.repositories.enabled=true spring.data.mongodb.database=abcde floatf)。 隐式转换是:

  1. int转换为i1
  2. 在添加后将结果转换为float