Rumah >pembangunan bahagian belakang >Golang >Mengapakah atur cara Go menggunakan `float32` memasuki gelung tak terhingga manakala atur cara serupa menggunakan `float64` ditamatkan, apabila kedua-duanya terkumpul 0.2 dan tolak 0.3 secara berulang sehingga melebihi 1.0?

Mengapakah atur cara Go menggunakan `float32` memasuki gelung tak terhingga manakala atur cara serupa menggunakan `float64` ditamatkan, apabila kedua-duanya terkumpul 0.2 dan tolak 0.3 secara berulang sehingga melebihi 1.0?

Linda Hamilton
Linda Hamiltonasal
2024-12-07 18:21:15286semak imbas

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?

Perbezaan Ketepatan Titik Terapung dalam Go: float32 vs float64

Dalam Go, nilai titik terapung boleh diwakili sama ada float32 atau float64 , dengan pelbagai tahap ketepatan. Dalam percubaan baru-baru ini, atur cara menunjukkan ralat titik terapung apabila menggunakan kedua-dua jenis float32 dan float64.

Atur cara mengumpul nilai titik terapung 0.2 berbilang kali, menolak 0.3 pada setiap lelaran sehingga nilai melebihi 1.0. Apabila menggunakan float64, program mengeluarkan 1.000000e 00 selepas 54 lelaran, serupa dengan tingkah laku program yang sama dalam C (apabila menggunakan double).

Walau bagaimanapun, apabila menggunakan float32 dalam program Go, ia memasuki infiniti gelung. Ketidakkonsistenan ini timbul daripada cara berbeza Go dan C mengendalikan perwakilan float32.

Memeriksa Perwakilan Titik Terapung

Menggunakan matematik.Float32bits dan matematik.Float64bits berfungsi, kami boleh memerhatikan bagaimana Go mewakili nilai perpuluhan sebagai binari IEEE 754 nilai:

float32(0.1): 00111101110011001100110011001101
float32(0.2): 00111110010011001100110011001101
float32(0.3): 00111110100110011001100110011010
float64(0.1): 0011111110111001100110011001100110011001100110011001100110011010
float64(0.2): 0011111111001001100110011001100110011001100110011001100110011010
float64(0.3): 0011111111010011001100110011001100110011001100110011001100110011

Analisis Ketepatan float32

Menukar nilai binari ini kepada perpuluhan mendedahkan bahawa nilai awal a dalam program Go menggunakan float32 menjadi:

0.20000000298023224
+ 0.10000000149011612
- 0.30000001192092896
= -7.4505806e-9

Nilai negatif ini menghalang gelung daripada mencapainya 1.0.

Perbezaan pelaksanaan C

Dalam C, tingkah laku berbeza disebabkan perbezaan dalam cara pemalar apungan dikendalikan. Pergi menghampiri 0.1 dengan perwakilan binari terdekat, manakala C mungkin memotong bit terakhir.

Go:   00111101110011001100110011001101 => 0.10000000149011612
C(?): 00111101110011001100110011001100 => 0.09999999403953552

Hasilnya, C membenarkan 0.1 diwakili dengan lebih tepat, menghasilkan hasil yang berbeza untuk gelung titik terapung apabila menggunakan float32.

Atas ialah kandungan terperinci Mengapakah atur cara Go menggunakan `float32` memasuki gelung tak terhingga manakala atur cara serupa menggunakan `float64` ditamatkan, apabila kedua-duanya terkumpul 0.2 dan tolak 0.3 secara berulang sehingga melebihi 1.0?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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