Ich habe kürzlich die Probleme mit der Gleitkommaberechnung von Java untersucht, relevante Informationen aus dem Internet abgefragt, einige Sortier- und Debugging-Vorgänge durchgeführt und schließlich diesen Artikel fertiggestellt. Jeder ist willkommen, auf die Fehler und Probleme hinzuweisen.
In Java sind mit Float deklarierte Variablen Gleitkommazahlen mit einfacher Genauigkeit und mit Double deklarierte Variablen sind Gleitkommazahlen mit doppelter Genauigkeit. Wie der Name schon sagt, belegen Entitäten vom Typ Double doppelt so viel Speicherplatz wie Float. float ist 4 Bytes und double ist 8 Bytes. Daten vom Typ Float und Double können Berechnungsergebnisse nicht genau darstellen, da Float und Double ungenaue Berechnungen sind. Sie können dies anhand des folgenden Codes sehen:
Kopieren Sie den Codecode wie folgt:
Öffentlicher Klassentest
{
public static void main(String[] args)
{
System.out.println(0,05 + 0,01);
System.out.println(1.0 - 0.42);
System.out.println(4.015 * 100);
System.out.println(123.3 / 100);
}
}
Das Ergebnis des Laufens ist:
0,060000000000000005
0,5800000000000001
401.49999999999994
1.23299999999999999
Um den gewünschten Effekt zu erzielen, können wir versuchen, mit java.text.DecimalFormat Gleitkommazahlen zu formatieren:
DecimalFormat kann Zahlen gemäß einem bestimmten Format formatieren. Häufig verwendete Formatierungszeichen sind #, 0 usw. Beispiel:
Kopieren Sie den Codecode wie folgt:
System.out.println(new java.text.DecimalFormat("0.00").format(3.125));
System.out.println(new java.text.DecimalFormat("0.00").format(3.135));
Aber das Ergebnis ist:
3.12
3.14
Dies liegt daran, dass DecimalFormat die halbgerade Rundung (ROUND_HALF_EVEN) verwendet, wenn es auf 5 rundet. Daher können mit DecimalForamt keine zuverlässigen Gleitkommazahlen ermittelt werden. Schließlich können wir die Verwendung von BigDecimal für genauere Berechnungen in Betracht ziehen:
BigDecimal bietet mehrere Konstruktoren für Gleitkommazahlen:
Kopieren Sie den Codecode wie folgt:
BigDecimal(double val) Übersetzt ein Double in ein BigDecimal.
BigDecimal(String val) Übersetzt die String-Darstellung eines BigDecimal in ein BigDecimal.
Die Verwendung doppelter Parameter zum Erstellen von Objekten führt jedoch zu ungenauen Werten. Nur das Erstellen von Objekten über String ist am genauesten.
Zum Beispiel:
Kopieren Sie den Codecode wie folgt:
BigDecimal bd1=new BigDecimal(0.05);
System.out.println(bd1.toString());
BigDecimal bd2=new BigDecimal("0.05");
System.out.println(bd2.toString());
Holen Sie sich das Ergebnis:
0,05000000000000000277555756156289135105907917022705078125
0,05
Daher müssen wir letztendlich String zum Erstellen von Objekten verwenden, damit die erhaltenen Ergebnisse möglichst genau sind. Wenn es sich um eine doppelte Zahl handelt, können wir außerdem Folgendes verwenden: BigDecimal.valueOf(double val). Der JDK-Quellcode ist wie folgt.
Kopieren Sie den Codecode wie folgt:
öffentlicher statischer BigDecimal-WertOf(double val)
{
return new BigDecimal(Double.toString(val));
}
Das Letzte, was zu beachten ist: Die Addition, Subtraktion, Multiplikation und Division von BigDecimal geben letztendlich ein neues BigDecimal-Objekt zurück. Da BigDecimal bei jeder Operation ein neues Objekt generiert, wird bei der Additionsoperation ein neues Objekt generiert ausgeführt wird, speichert a den Wert nach der Additionsoperation nicht. Die korrekte Verwendung sollte a=a.add(b) sein.