提供的程式碼片段示範了在不同編譯器上使用最佳化時浮點計算結果的差異。在 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中文網其他相關文章!