首頁 > 後端開發 > Golang > 為什麼使用「float32」的 Go 程式會進入無限循環,而使用「float64」的類似程式會終止,當兩者迭代累加 0.2 並減去 0.3 直到超過 1.0 時?

為什麼使用「float32」的 Go 程式會進入無限循環,而使用「float64」的類似程式會終止,當兩者迭代累加 0.2 並減去 0.3 直到超過 1.0 時?

Linda Hamilton
發布: 2024-12-07 18:21:15
原創
312 人瀏覽過

Why does a Go program using `float32` enter an infinite loop while a similar program using `float64` terminates, when both accumulate 0.2 and subtract 0.3 iteratively until exceeding 1.0?

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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板