gpt4 book ai didi

c++ - 为什么 float 计算和转换在调试和发布配置中显示不同的结果?

转载 作者:可可西里 更新时间:2023-11-01 16:37:04 25 4
gpt4 key购买 nike

这对我来说真的是一个奇怪的错误,我花了很长时间才弄清楚发生了什么。为了简化事情和重现,只需使用 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 优化器工作的人。我会向他发送错误报告。

更新:

这是他们的回应:

Hi Alex, thanks for this bug report. I’ll try to fix this for the upcoming VC++ release, but it might not make it.

FWIW, the bug doesn’t reproduce if you throw /arch:SSE2, and since we are enabling /arch:SSE2 by default for the next VC++ release (https://connect.microsoft.com/VisualStudio/feedback/details/688736/compiler-generates-sse-instructions-without-arch-sse).

So, the default behavior will show that this bug is fixed. But if you revert back to the old FP model (throw /arch:IA32) the bug may still be present.

Eric

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

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com