为什么浮动计算和强制转换在调试和发布配置中显示不同的结果
Why floating calculation and casting shows different result in debug and release configuration?
这对我来说真的是一个奇怪的bug,我花了很长时间才弄清楚发生了什么。为了简化和重现,只需使用VS2005创建一个空的win32控制台应用程序,并在主方法中使用以下代码:
float a = 411.00418f;
float b = 1.0f;
float c = 0.076279849f;
unsigned short result = (unsigned short)( (a-b)/c );
unsigned short result2 = (unsigned short)( (float)((a-b)/c) );
// Debug: 5374, 5375
// Release: 5374, 5374
printf("%d, %dn", result, result2);
为什么result2在调试/发布模式下显示不同的值?
在MSVC中,默认浮点模式为precise (/fp:precise)
。这意味着优化器可以进行某些优化以提高准确性或性能。
尝试将模式更改为strict (/fp:strict)
。这将使编译器在舍入等方面遵循严格的浮点规则。
(编辑:strict (/fp:strict)
在这种情况下似乎不起作用…)
如果您查看优化构建的反汇编,您可以看到整个计算已经折叠并优化。
push 5374 ; 000014feH
push 5374 ; 000014feH
push OFFSET ??_C@_07MHMABKGB@?$CFd?0?5?$CFd?6?$AA@
call DWORD PTR __imp__printf
add esp, 12 ; 0000000cH
EDIT:对我来说,这看起来像是一个编译器优化器错误。
在strict (/fp:strict)
下,以下代码会产生不同的结果:
float a = 411.00418f;
float b = 1.0f;
float c = 0.076279849f;
unsigned short result1 = (unsigned short)((float)((a-b)/c));
float d = (float)((a-b)/c);
unsigned short result2 = (unsigned short)( d );
输出:
5374, 5375
将(float)((a-b)/c)
拉出到单独的赋值中不应影响strict (/fp:strict)
下的结果。
我认识一个在MSVC优化器上工作的人。我会给他发一份错误报告
更新:
以下是他们的回应:
嗨,亚历克斯,谢谢你的错误报告。我会设法为即将发布的VC++,但它可能无法成功。
FWIW,如果你抛出/arch:SSE2,这个错误就不会重现,因为我们正在为下一个VC++版本默认启用/arch:SSE2(https://connect.microsoft.com/VisualStudio/feedback/details/688736/compiler-generates-sse-instructions-without-arch-sse)。
因此,默认行为将显示此错误已修复。但是如果如果恢复到旧的FP模型(throw/arch:IA32),则错误可能仍然存在。
Eric
所以他们已经确认这是一个错误
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 字符串-C++后显示的随机字符
- 继承期间显示未知行为的子类
- 无法找到/读取配置文件.conf-FileIOException
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- 程序崩溃并显示"std::out_of_range"错误
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 一种在C++中读取TXT配置文件的简单方法
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 为什么在C的循环中使用printf的Rust代码不显示输出,而在C++的循环中显示std::cout
- 生成MRPT库时cmake配置失败
- 从数据库实时显示QT c++中的数据
- 如何配置MSVC以使用__FILE__显示头文件的相对路径
- Qt 4.8.5 配置.exe只显示选项
- 为什么浮动计算和强制转换在调试和发布配置中显示不同的结果
- 如何确保滴管工具返回一致的值,尽管不同的显示配置文件
- Boost日志在使用配置文件时不显示严重性或按严重性过滤
- 配置gtest仅在控制台中显示失败的测试