Go 中的浮點精度差異:float32 與float64
在Go 中,浮點值可以表示為float32 或具有不同的精度等級。在最近的一次實驗中,一個程式在使用 float32 和 float64 類型時演示了浮點錯誤。
程式多次累加浮點值 0.2,每次迭代減去 0.3,直到值超過 1.0。當使用 float64 時,程式在 54 次迭代後輸出 1.000000e 00,類似於 C 中相同程式的行為(使用 double 時)。
但是,當在 Go 程式中使用 float32 時,會進入無限環形。這種不一致是由於 Go 和 C 處理 float32 表示的不同方式造成的。
檢查浮點表示
使用 math.Float32bits 和 math.Float64bits 函數,我們可以觀察 Go 如何將十進位值表示為 IEEE 754二進位value:
float32(0.1): 00111101110011001100110011001101 float32(0.2): 00111110010011001100110011001101 float32(0.3): 00111110100110011001100110011010 float64(0.1): 0011111110111001100110011001100110011001100110011001100110011010 float64(0.2): 0011111111001001100110011001100110011001100110011001100110011010 float64(0.3): 0011111111010011001100110011001100110011001100110011001100110011
float32 精度分析
將這些二進位值轉換為十進位可以發現,使用float32 的Go 程式中
0.20000000298023224 + 0.10000000149011612 - 0.30000001192092896 = -7.4505806e-9
這個負值會阻止循環到達1.0.
C 實現差異
在C 中,由於處理浮點常數的方式不同,行為也有所不同。 Go 用最接近的二進位表示來近似 0.1,而 C 可能會截斷最後一位。
Go: 00111101110011001100110011001101 => 0.10000000149011612 C(?): 00111101110011001100110011001100 => 0.09999999403953552
因此,C 允許更準確地表示 0.1,從而導致浮點循環產生不同的結果當使用 float32 時。
以上是為什麼使用「float32」的 Go 程式會進入無限循環,而使用「float64」的類似程式會終止,當兩者迭代累加 0.2 並減去 0.3 直到超過 1.0 時?的詳細內容。更多資訊請關注PHP中文網其他相關文章!