Go Lang Gleitkomma-Präzision: Float32 vs. Float64
Um die Feinheiten der Gleitkomma-Arithmetik in Go zu veranschaulichen, betrachten Sie das folgende Programm, das dies demonstriert Auswirkung der Präzision:
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) }
Dieses Programm zeigt das erwartete Verhalten in C bei Verwendung des Double-Typs. Drucken:
After 54 iterations, a = 1.000000e+00
Bei Verwendung von float32 in Go gerät das Programm jedoch in eine Endlosschleife. Das Ändern des C-Programms zur Verwendung von Float anstelle von Double führt zu einem anderen Ergebnis:
After 27 iterations, a = 1.600000e+00
Um diese Diskrepanz zu verstehen, vertiefen Sie sich in die zugrunde liegenden Binärdarstellungen mit math.Float32bits und 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
Die Konvertierung dieser Binärwerte in Dezimalwerte zeigt, dass für float32 der Anfangswert von a ist wird zu:
0.20000000298023224 + 0.10000000149011612 - 0.30000001192092896 = -7.4505806e-9
Dieser negative Wert kann niemals 1 ergeben, was zur beobachteten Endlosschleife führt.
Im Gegensatz dazu ergibt sich das Verhalten von C aus den Unterschieden in den Rundungsstrategien. Go rundet das letzte Bit ab, während C es wahrscheinlich abschneidet. Folglich stellt Go 0,1 als den ihm am nächsten kommenden Wert dar:
Go: 00111101110011001100110011001101 => 0.10000000149011612 C(?): 00111101110011001100110011001100 => 0.09999999403953552
Zusammenfassend lässt sich sagen, dass sowohl Go als auch C 0,1 in einer Gleitkommazahl nicht genau darstellen können, Go jedoch die nächstliegende Näherung verwendet, während C es je nach Fall unterschiedlich handhaben kann die Umsetzung.
Das obige ist der detaillierte Inhalt vonGo vs. C: Warum verursacht Gleitkomma-Präzision eine Endlosschleife in Gos Float32, aber nicht in Cs Double?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!