提供的代码片段演示了在不同编译器上使用优化时浮点计算结果的差异。在 Visual Studio 2008 和未经优化的 g 上,代码会产生预期的输出。然而,启用 g 优化 (O1 - O3) 后,它会显示不正确的结果。
要了解此行为的根本原因,必须注意 Intel x86 处理器使用 80 位扩展精度在内部处理浮点计算。相比之下,C 中的 double 数据类型通常具有 64 位宽度。
优化级别影响 CPU 中的浮点值存储的频率。记忆。当值在存储期间从 80 位精度转换为 64 位精度时,这可能会导致舍入错误。
为了确保跨优化级别的浮点结果一致,gcc提供 -ffloat-store 选项。通过使用此选项,浮点值始终存储在内存中,从而防止由寄存器存储引起的任何舍入错误。
或者,使用 long double 数据类型,其在 gcc 上通常具有 80 位的宽度,可以完全消除舍入问题。
Visual Studio 很有趣即使启用了扩展浮点精度,2008 也能提供正确的结果。这表明 VS2008 与 g 相比,处理舍入和优化的方式不同。
虽然不是绝对必要使用 -ffloat-store,但建议在定位时使用 -ffloat-store在内部使用扩展浮点精度的系统,以确保跨优化级别的可预测行为。
对于 x86_64 构建,不会出现此问题,因为编译器默认使用 SSE 寄存器来表示 float 和 double,从而消除了扩展精度的使用。 gcc 编译器选项 -mfpmath 允许您控制此行为。
以上是为什么不同编译器中的优化浮点结果不同?的详细内容。更多信息请关注PHP中文网其他相关文章!