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
919 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!

sumber:php.cn
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