analysieren
JavaScript hat nur eine Nummer-Typ-Nummer, und alle Zahlen in JavaScript sind im Standardformat IEEE-754 dargestellt. Das Präzisionsproblem der Floating-Punkt-Zahlen ist für JavaScript nicht nur eindeutig, da einige Dezimalstellen unendliche Ziffern in Binärer darstellen:
Dezimaler binär
0,1 0,0001 1001 1001 1001 ...
0,2 0,0011 0011 0011 0011 ...
0,3 0.0100 1100 1100 1100 ...
0.4 0.0110 0110 0110 0110 ...
0,5 0,1
0,6 0,1001 1001 1001 1001 ...
So kann sein Programm beispielsweise "1.1" tatsächlich darstellen, sondern nur ein gewisses Maß an Genauigkeit erreichen.
1.09999999999999999999
Das Problem in JavaScript ist komplizierter. Hier finden Sie nur einige Testdaten in Chrome:
Eingang und Ausgabe
1,0-0,9 == 0.1 Falsch
1,0-0,8 == 0,2 Falsch
1,0-0,7 == 0,3 Falsch
1,0-0,6 == 0,4 TRUE
1,0-0,5 == 0,5 true
1,0-0.4 == 0.6 TRUE
1,0-0.3 == 0.7 TRUE
1,0-0,2 == 0,8 TRUE
1,0-0.1 == 0,9 TRUE
lösen
Wie vermeiden Sie diese Art von Nicht-Schlupfproblem mit 1,0-0,9! = 0,1? Hier ist eine Lösung, die derzeit häufiger verwendet wird.
Die Codekopie lautet wie folgt:
(1.0-0.9) .Tofixed (Ziffern) // tofixed () Die Genauigkeitsparameter müssen zwischen 0 und 20 liegen
Parsefloat ((1.0-0.9) .Tofixed (10)) === 0.1 // Das Ergebnis ist wahr
Parsefloat ((1.0-0.8) .Tofixed (10)) === 0.2 // Das Ergebnis ist wahr
Parsefloat ((1.0-0.7) .Tofixed (10)) === 0.3 // Das Ergebnis ist wahr
Parsefloat ((11.0-11.8) .Tofixed (10)) === -0.8 // Das Ergebnis ist wahr
Methodenraffinierung
Die Codekopie lautet wie folgt:
// Verwenden Sie die ISEqual Tool -Methode, um festzustellen, ob die Werte gleich sind oder nicht
Funktion isqual (Nummer1, Nummer2, Ziffern) {
Ziffern = digits == undefiniert?
Rückgabenummer1.Tofixed (Ziffern) === Number2.ToFixed (Ziffern);
}
isequal (1,0-0,7, 0,3);
// native Erweiterungsmethode, den objektorientierten Stil bevorzugen
Number.Prototype.isequal = Funktion (Nummer, Ziffern) {
Ziffern = digits == undefiniert?
return this.toFixed (Ziffern) === number.tofixed (Ziffern);
}
(1.0-0.7) .isequal (0,3);