The*_*ook 8 c++ compiler-optimization visual-studio
我在代码中有以下语句:
int a = (int)( (float)(b * 1000) / (float)c + .5f );
Run Code Online (Sandbox Code Playgroud)
在哪里b也是int,并且c是一个unsigned int具有常数值(在我的测试运行中为15)
这个语句在while循环中b,每次迭代时都会增加1.
这段代码工作正常,直到我决定在Visual Studio中打开优化标志(最大化速度).之后,a会随机进入溢出(即它的值为-2147483647).在进一步研究这种溢出曾经发生在不同的值b.在我观察到的测试运行中,溢出发生的b值在9-12之间.
解决问题的方法是进行如下图所示的小改动:
int a = (int)( (b * 1000.f) / c + .5f );
Run Code Online (Sandbox Code Playgroud)
关于这是如何帮助的任何想法?它工作正常,但我不知道为什么?
编辑:根据评论添加更多信息:
在记录时,我观察到:
(float)(b * 1000) / (float)c + .5f
被评估为一个非常大的值,当类型转换int为导致溢出时.独立,float(b*1000)并float(c)正在正确计算不过.
b * 1000是int * int,因此会发生整数乘法,并且溢出的风险较高。(有符号整数算术中的溢出是未定义的行为)
投射b到float也可以解决这个问题。
int a = (int)( (float)b * 1000 / (float)c + .5f );
Run Code Online (Sandbox Code Playgroud)