啟用最佳化的浮點舍入差異:編譯器錯誤或最佳化困境?
浮點計算通常會表現出意外的行為,尤其是在啟用編譯器最佳化。考慮以下程式碼片段:
#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中文網其他相關文章!