Ketepatan Titik Terapung Go Lang: Float32 vs Float64
Untuk menggambarkan selok-belok aritmetik titik terapung dalam Go, pertimbangkan program berikut yang menunjukkan kesan ketepatan:
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) }
Program ini mempamerkan tingkah laku yang dijangkakan dalam C apabila menggunakan jenis berganda, mencetak:
After 54 iterations, a = 1.000000e+00
Walau bagaimanapun, apabila menggunakan float32 dalam Go, atur cara memasuki gelung tak terhingga. Mengubah suai atur cara C untuk menggunakan apungan dan bukannya berganda menghasilkan hasil yang berbeza:
After 27 iterations, a = 1.600000e+00
Untuk memahami percanggahan ini, teliti perwakilan binari asas menggunakan matematik.Float32bits dan matematik.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
Menukar nilai binari ini kepada perpuluhan mendedahkan bahawa untuk float32, nilai awal a menjadi:
0.20000000298023224 + 0.10000000149011612 - 0.30000001192092896 = -7.4505806e-9
Nilai negatif ini tidak boleh dijumlahkan hingga 1, yang membawa kepada gelung tak terhingga yang diperhatikan.
Sebaliknya, tingkah laku C berpunca daripada perbezaan dalam strategi pembundaran. Pergi pusingan bit terakhir, manakala C mungkin memangkasnya. Akibatnya, Go mewakili 0.1 sebagai nilai yang paling hampir dengannya:
Go: 00111101110011001100110011001101 => 0.10000000149011612 C(?): 00111101110011001100110011001100 => 0.09999999403953552
Ringkasnya, kedua-dua Go dan C tidak boleh mewakili 0.1 dengan tepat dalam apungan, tetapi Go menggunakan anggaran terdekat manakala C mungkin mengendalikannya secara berbeza bergantung pada pelaksanaannya.
Atas ialah kandungan terperinci Go vs. C: Mengapa Ketepatan Titik Terapung Menyebabkan Gelung Infiniti dalam Float32 Go tetapi Tidak dalam Double C?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!