Wenn ich Sie frage, was ist 0,1 + 0,2? Vielleicht werfen Sie mir einen leeren Blick zu, 0,1 + 0,2 = 0,3 Ah, müssen Sie noch fragen? Auch Kinder im Kindergarten können eine solche pädiatrische Frage beantworten. Aber Sie wissen, dass das gleiche Problem in einer Programmiersprache möglicherweise nicht so einfach ist, wie man es sich vorstellt.
Glauben Sie es nicht? Schauen wir uns zunächst einen Teil von JS an.
var numA = 0,1;
var numB = 0,2;
alarm( (numA + numB) === 0,3 );
Das Ausführungsergebnis ist falsch. Ja, als ich diesen Code zum ersten Mal sah, ging ich davon aus, dass er wahr ist, aber die Ausführungsergebnisse haben mich überrascht. Ist meine Öffnungsmethode falsch? Nein, nein. Versuchen wir noch einmal, den folgenden Code auszuführen, und wir werden wissen, warum das Ergebnis falsch ist.
var numA = 0,1;
var numB = 0,2;
alarm(numA + numB);
Es stellt sich heraus, dass 0,1 + 0,2 = 0,30000000000000004. Ist es nicht seltsam? Tatsächlich treten bei den vier arithmetischen Operationen von Gleitkommazahlen in fast allen Programmiersprachen Probleme auf, die Präzisionsfehlern ähneln. In Sprachen wie C++/C#/Java wurden jedoch Methoden gekapselt, um Präzisionsprobleme zu vermeiden. und JavaScript ist ein schwacher Typ für Gleitkommazahlen aus dem Designkonzept, daher ist das Problem des Präzisionsfehlers besonders ausgeprägt. Lassen Sie uns analysieren, warum es diesen Genauigkeitsfehler gibt und wie man ihn beheben kann.
Zunächst müssen wir aus der Computerperspektive über das scheinbar pädiatrische Problem 0,1 + 0,2 nachdenken. Wir wissen, dass das, was Computer lesen können, binär und nicht dezimal ist. Konvertieren wir also zunächst 0,1 und 0,2 in Binärzahlen und schauen wir uns Folgendes an:
0,1 => 0,0001 1001 1001 1001… (Endlosschleife)
0,2 => 0,0011 0011 0011 0011… (Endlosschleife)
Der Dezimalteil einer Gleitkommazahl mit doppelter Genauigkeit unterstützt bis zu 52 Bit, sodass wir nach der Addition der beiden eine Zeichenfolge von 0,0100110011001100110011001100110011001100110011001100 erhalten Die Binärzahl wird aufgrund der Beschränkung der Dezimalstellen von Gleitkommazahlen gekürzt. Zu diesem Zeitpunkt konvertieren wir sie in eine Dezimalzahl und sie wird zu 0,30000000000000004.
Das war's also. Wie kann man dieses Problem lösen? Das gewünschte Ergebnis ist 0,1 + 0,2 === 0,3 Ah! ! !
Eine der einfachsten Lösungen besteht darin, klare Präzisionsanforderungen anzugeben. Bei der Rückgabe des Werts rundet der Computer automatisch, wie zum Beispiel:
var numA = 0,1;
var numB = 0,2;
alarm( parseFloat((numA + numB).toFixed(2)) === 0.3 );
Aber offensichtlich ist dies keine endgültige Methode. Es wäre großartig, wenn es eine Methode gäbe, die uns helfen könnte, das Präzisionsproblem dieser Gleitkommazahlen zu lösen. Probieren wir diese Methode aus:
Math.formatFloat = function(f, Ziffer) {
var m = Math.pow(10, Ziffer);
return parseInt(f * m, 10) / m;
}
var numA = 0,1;
var numB = 0,2;
Alert(Math.formatFloat(numA + numB, 1) === 0.3);
Was bedeutet diese Methode? Um Genauigkeitsunterschiede zu vermeiden, müssen wir die zu berechnende Zahl mit 10 bis zur n-ten Potenz multiplizieren, sie in eine ganze Zahl umwandeln, die der Computer genau erkennen kann, und sie dann durch 10 bis zur n-ten Potenz dividieren Programmiersprachen behandeln Präzisionsunterschiede. Wir werden es verwenden, um den Präzisionsfehler von Gleitkommazahlen in JS zu behandeln.
Wenn Sie das nächste Mal jemand fragt, was 0,1 + 0,2 ist, sollten Sie mit Ihrer Antwort vorsichtig sein! !