Gleitkomma-Vergleichsrätsel
Bedenken Sie den folgenden C-Code:
int main() { float a = 0.7; float b = 0.5; if (a < 0.7) { if (b < 0.5) printf("2 are right"); else printf("1 is right"); } else printf("0 are right"); }
Sie würden intuitiv erwarten, dass die Ausgabe so ist sei „0 sind richtig.“ Das überraschende Ergebnis ist jedoch: „1 ist richtig.“ Warum passiert das?
Die Fallstricke des Gleitkomma-Vergleichs
Der Schlüssel liegt in den Unterschieden zwischen Gleitkomma- und Zahlen mit doppelter Genauigkeit in C. Im Code werden die Variablen a und b als Floats deklariert, bei denen es sich um 32-Bit-Gleitkommazahlen handelt. Allerdings beinhalten beide Vergleiche (a < 0,7 und b < 0,5) Doubles, da die Literale 0,7 und 0,5 als Doubles behandelt werden.
Während des Vergleichs werden die Float-Variablen zu Doubles heraufgestuft, was a ermöglicht höhere Reichweite und Präzision. Aufgrund der begrenzten Präzision von Gleitkommazahlen kann diese Konvertierung jedoch zu geringfügigen Artefakten führen. In diesem Fall entspricht 0,7 als Float nicht genau 0,7 als Double.
Konkret wird 0,7 als Float im IEEE 754-Standard als 0x3f000000 dargestellt. Bei einer Beförderung zum Double ist dieser Wert keine exakte Darstellung von 0,7. Stattdessen wird es etwas größer, etwa 0x3f00000000000000 (ungefähr 0,7000000000000001).
Die Ursache des unerwarteten Ergebnisses
Als Ergebnis dieser Aktion wird die Bedingung a < 0,7 wird wahr, weil die Doppeldarstellung von a geringfügig kleiner als 0,7 ist. Anschließend erfolgt der zweite Vergleich b < 0,5 wird als falsch ausgewertet, da b (exakt als Double dargestellt) gleich 0,5 ist. Daher gibt der Code „1 ist richtig“ aus.
Lösungen
Um dieses Problem zu beheben, können Sie entweder:
Das obige ist der detaillierte Inhalt vonWarum führt der Vergleich von Floats mit Doppelliteralen in C zu unerwarteten Ergebnissen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!