对我来说,这确实是一个怪异的错误,我花了很长时间才弄清楚正在发生的事情。为了简化和重现,只需使用VS2005创建一个空的win32控制台应用程序,然后在main方法中使用以下代码:

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, %d\n", result, result2);

为什么result2在调试/ Release模式下显示不同的值?

最佳答案

在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

编辑:对我来说,这似乎是编译器优化器的错误。

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优化程序的人。我将向他发送错误报告。

更新:

这是他们的回应:



,所以他们已经确认这是一个错误。

关于c++ - 为什么 float 计算和强制转换在调试和发布配置中显示不同的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9232889/

10-11 16:39