Rumah > pembangunan bahagian belakang > Golang > Go vs. C: Mengapa Ketepatan Titik Terapung Menyebabkan Gelung Infiniti dalam Float32 Go tetapi Tidak dalam Double C?

Go vs. C: Mengapa Ketepatan Titik Terapung Menyebabkan Gelung Infiniti dalam Float32 Go tetapi Tidak dalam Double C?

Barbara Streisand
Lepaskan: 2024-12-09 17:01:10
asal
987 orang telah melayarinya

Go vs. C: Why Does Floating-Point Precision Cause an Infinite Loop in Go's Float32 but Not in C's Double?

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)
}
Salin selepas log masuk

Program ini mempamerkan tingkah laku yang dijangkakan dalam C apabila menggunakan jenis berganda, mencetak:

After 54 iterations, a = 1.000000e+00
Salin selepas log masuk

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
Salin selepas log masuk

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
Salin selepas log masuk

Menukar nilai binari ini kepada perpuluhan mendedahkan bahawa untuk float32, nilai awal a menjadi:

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9
Salin selepas log masuk

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
Salin selepas log masuk

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!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan