用于C ++中类型转换的Visual Studio编译器优化

时间:2016-02-29 09:41:11

标签: c++ visual-studio compiler-optimization

我在代码中有以下声明:

int a = (int)( (float)(b * 1000) / (float)c + .5f );

其中b也是intc是一个unsigned int,其值为常数(在我的测试运行中为15)

此语句位于while循环中,其中b在每次迭代时递增1。

此代码工作正常,直到我决定在Visual Studio中打开优化标记(最大化速度)。之后,a会随机进入溢出(即它的值为-2147483647)。在进一步调查时,这种溢出曾经发生在不同的b值。在我观察到的测试运行中,溢出发生的b值在9-12之间。

解决问题的方法是进行如下图所示的小改动:

int a = (int)( (b * 1000.f) / c + .5f );

有关这是如何帮助的任何想法?它工作正常,但我不明白为什么?

编辑:根据评论添加更多信息:

在记录时,我观察到:

(float)(b * 1000) / (float)c + .5f

被评估为一个非常大的值,当类型转换为int导致溢出时。然而,单独地,float(b*1000)float(c)被正确计算。

2 个答案:

答案 0 :(得分:1)

b * 1000很有可能溢出int类型;执行此操作的行为是 undefined

删除所有那些混淆的强制转型,并使用

b * 1000.0 / c + 0.5

代替。 1000.0double字面值,会导致第一个字词以浮点计算。

在转换回int之前,您应该检查表达式的大小,特别是如果c很小的话。 std::numeric_limits对此很有用。

答案 1 :(得分:0)

b * 1000int * int,因此会发生整数乘法,并且存在更高的溢出风险。 (有符号整数aritimetic中的溢出是未定义的行为

b投射到float也可以解决此问题。

int a = (int)( (float)b * 1000 / (float)c + .5f );