Heim > Backend-Entwicklung > Golang > Go vs. C: Warum verursacht Gleitkomma-Präzision eine Endlosschleife in Gos Float32, aber nicht in Cs Double?

Go vs. C: Warum verursacht Gleitkomma-Präzision eine Endlosschleife in Gos Float32, aber nicht in Cs Double?

Barbara Streisand
Freigeben: 2024-12-09 17:01:10
Original
918 Leute haben es durchsucht

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

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)
}
Nach dem Login kopieren

Dieses Programm zeigt das erwartete Verhalten in C bei Verwendung des Double-Typs. Drucken:

After 54 iterations, a = 1.000000e+00
Nach dem Login kopieren

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
Nach dem Login kopieren

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
Nach dem Login kopieren

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
Nach dem Login kopieren

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
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage