Go Lang 浮點精度:Float32 與 Float64
為了說明 Go中浮點運算的複雜性,請考慮以下程序,該程序演示了精度的影響:
func main() { a := float64(0.2) a += 0.1 a -= 0.3 var i int for i = 0; a < 1.0; i++ { a += a } fmt.Printf("After %d iterations, a = %e\n", i, a) }
該程序表現出預期的行為C 在使用double 類型時,打印:
After 54 iterations, a = 1.000000e+00
但是在Go 中使用float32 時,程式會進入死循環。修改C 程式以使用float 而不是double 會產生不同的結果:
After 27 iterations, a = 1.600000e+00
要理解這種差異,請使用math.Float32bits 和math.Float64bits 深入研究底層二進位表示:
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,a 的初始值變成:
0.20000000298023224 + 0.10000000149011612 - 0.30000001192092896 = -7.4505806e-9
這個負值永遠不可能等於 1,導致觀察到的無限循環。
相反,C 的行為源自於舍入策略的差異。 Go 會捨入最後一位,而 C 可能會將其裁切掉。因此,Go 將0.1 表示為最接近它的值:
Go: 00111101110011001100110011001101 => 0.10000000149011612 C(?): 00111101110011001100110011001100 => 0.09999999403953552
總之,Go 和C 都不能精確地表示浮點數中的0.1,但Go 使用最接近的近似值,而C 可能會根據不同情況進行不同的處理。實施。
以上是Go 與 C:為什麼浮點精準度會在 Go 的 Float32 中導致無限循環,而在 C 的 Double 中卻不會?的詳細內容。更多資訊請關注PHP中文網其他相關文章!