启用优化的浮点舍入差异:编译器错误或优化困境?
浮点计算通常会表现出意外的行为,尤其是在启用编译器优化。考虑以下代码片段:
#include <cstdlib> #include <iostream> #include <cmath> double round(double v, double digit) { double pow = std::pow(10.0, digit); double t = v * pow; double r = std::floor(t + 0.5); return r / pow; } int main() { std::cout << round(4.45, 1) << std::endl; std::cout << round(4.55, 1) << std::endl; }
预期输出:
4.5 4.6
但是,当使用 g 进行优化(O1 - O3)编译此代码时,输出变为:
4.5 4.5
原因差异:
这种不一致源于 x86 处理器内部使用 80 位扩展精度进行浮点计算。然而,双精度变量通常是 64 位宽。当浮点值从 CPU 寄存器存储到内存时,它们会从 80 位精度舍入到 64 位精度。此舍入可能会引入轻微错误。
优化级别的影响:
不同的优化级别可能会影响浮点值保存到内存中的频率。优化级别越高,这种情况发生的频率就越高。结果,舍入误差变得更加明显。
解决方案:
进一步的考虑因素:
以上是为什么启用编译器优化后,我的浮点舍入代码会产生不同的结果?的详细内容。更多信息请关注PHP中文网其他相关文章!