【问题标题】:Convert float to int implicit vs explicit (cast) discrepancy将 float 转换为 int 隐式与显式(强制转换)差异
【发布时间】:2016-03-15 16:28:13
【问题描述】:
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. 我希望结果类似于隐式转换的结果,但没有编译警告。有可能吗?

平台是Windows7、VS2010或2013。

【问题讨论】:

  • 你没有显示输出。
  • 能否也提供结果
  • @grunt 不要编辑你自己的问题,以免改变问题,尤其是在收到好的答案之后。
  • @Pete Becker 不同意编辑:将“显式转换”更改为“显式转换”。原始术语是正确的,并且与 C 规范一致。建议恢复。
  • @chux -- 演员表总是显式的,所以“显式演员表”是多余的。但编辑主要是关于“隐式演员”。强制转换是您在源代码中编写的内容,用于告诉编译器进行转换。转换可以是显式的(即使用强制转换)或隐式的。

标签: c casting floating-point


【解决方案1】:

要分析这个,首先要把a += b改写成a = a + b。

由于显式转换,i + (int)f 将以整数算术计算。

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

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

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

【讨论】:

  • 所以回答问题#2:i = (int)((float)i + f)?
  • "不要将 += 用于混合类型":您是否也将此应用于 float f = 2.8f; ... f += 0.1;?
  • 我不会写f += 0.1,不:幕后发生的事情太多了。也就是说,我不再使用float。
【解决方案2】:

这里是更详细的情况分解,以编译器生成的代码和逐行执行后变量(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 被转换为浮点数(我建议您阅读此 wiki),然后将结果转换回整数以分配给整数 L 值。

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

警告 C4305:“+=”:从“double”截断为“float”

【讨论】:

    【解决方案3】:

    因为您的显式转换是在添加之前完成的(floatf 到int)。 隐式转换是:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多