最適化が有効な場合の浮動小数点丸めの不一致: コンパイラのバグまたは最適化のジレンマ?
浮動小数点計算は、特に次の場合に予期しない動作を示すことがよくあります。コンパイラの最適化が有効になっています。次のコード スニペットを考えてみましょう:
#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 ビットの拡張精度を使用しているという事実に起因します。ただし、double 変数は通常 64 ビット幅です。浮動小数点値が CPU レジスタからメモリに格納されるとき、浮動小数点値は 80 ビット精度から 64 ビット精度に丸められます。この丸めにより、わずかな誤差が生じる可能性があります。
最適化レベルの影響:
最適化レベルが異なると、浮動小数点値がメモリに保存される頻度に影響を与える可能性があります。最適化レベルが高くなると、この問題がより頻繁に発生します。その結果、丸め誤差がより顕著になります。
解決策:
その他の考慮事項:
以上がコンパイラの最適化を有効にすると、浮動小数点丸めコードが異なる結果を生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。