Java Language
BigDecimal
Suche…
Einführung
Die BigDecimal- Klasse bietet Operationen für Arithmetik (Addieren, Subtrahieren, Multiplizieren, Dividieren), Skalierungsmanipulation, Rundung, Vergleich, Hashing und Formatkonvertierung. Das BigDecimal steht für unveränderliche, beliebig genaue, vorzeichenbehaftete Dezimalzahlen. Diese Klasse wird für die Notwendigkeit einer hochgenauen Berechnung verwendet.
BigDecimal-Objekte sind unveränderlich
Wenn Sie mit BigDecimal berechnen möchten, müssen Sie den zurückgegebenen Wert verwenden, da BigDecimal-Objekte unveränderlich sind:
BigDecimal a = new BigDecimal("42.23");
BigDecimal b = new BigDecimal("10.001");
a.add(b); // a will still be 42.23
BigDecimal c = a.add(b); // c will be 52.231
Vergleich von BigDecimals
Die Methode compareTo
sollte zum Vergleichen von BigDecimals
:
BigDecimal a = new BigDecimal(5);
a.compareTo(new BigDecimal(0)); // a is greater, returns 1
a.compareTo(new BigDecimal(5)); // a is equal, returns 0
a.compareTo(new BigDecimal(10)); // a is less, returns -1
Normalerweise sollten Sie die equals
Methode nicht verwenden, da zwei BigDecimals
nur dann als gleich betrachtet werden, wenn sie gleichwertig und ebenfalls skaliert sind :
BigDecimal a = new BigDecimal(5);
a.equals(new BigDecimal(5)); // value and scale are equal, returns true
a.equals(new BigDecimal(5.00)); // value is equal but scale is not, returns false
Mathematische Operationen mit BigDecimal
Dieses Beispiel zeigt, wie grundlegende mathematische Operationen mit BigDecimals ausgeführt werden.
1.Zusatz
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a + b
BigDecimal result = a.add(b);
System.out.println(result);
Ergebnis: 12
2. Subtraktion
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a - b
BigDecimal result = a.subtract(b);
System.out.println(result);
Ergebnis: -2
3. Multiplikation
Beim Multiplizieren von zwei BigDecimal
erhält das Ergebnis eine Skalierung, die der Summe der Skalen der Operanden entspricht.
BigDecimal a = new BigDecimal("5.11");
BigDecimal b = new BigDecimal("7.221");
//Equivalent to result = a * b
BigDecimal result = a.multiply(b);
System.out.println(result);
Ergebnis: 36.89931
Um den Maßstab des Ergebnisses zu ändern, verwenden Sie die überladene Multiplikationsmethode, mit der MathContext
- ein Objekt, das die Regeln für Operatoren beschreibt, insbesondere die Genauigkeit und den Rundungsmodus des Ergebnisses. Weitere Informationen zu den verfügbaren Rundungsmodi finden Sie in der Oracle-Dokumentation.
BigDecimal a = new BigDecimal("5.11");
BigDecimal b = new BigDecimal("7.221");
MathContext returnRules = new MathContext(4, RoundingMode.HALF_DOWN);
//Equivalent to result = a * b
BigDecimal result = a.multiply(b, returnRules);
System.out.println(result);
Ergebnis: 36,90
4.Division
Die Division ist etwas komplizierter als die anderen Rechenoperationen. Betrachten Sie beispielsweise das folgende Beispiel:
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
BigDecimal result = a.divide(b);
System.out.println(result);
Wir würden erwarten, dass dies etwas ähnelt: 0.7142857142857143, aber wir würden bekommen:
Ergebnis: java.lang.ArithmeticException: Dezimale Erweiterung ohne Endung; kein genau darstellbares Dezimalergebnis.
Dies würde perfekt funktionieren, wenn das Ergebnis eine abschließende Dezimalzahl wäre, wenn ich 5 durch 2 teilen wollte, aber für jene Zahlen, die nach der Division ein nicht abschließendes Ergebnis ergeben würden, würden wir eine ArithmeticException
. Im realen Szenario kann man die Werte, die während der Division auftreten würden, nicht vorhersagen. Daher müssen die Skalierung und der Rundungsmodus für die Division BigDecimal angegeben werden. Weitere Informationen zum Skalierungs- und Rundungsmodus finden Sie in der Oracle-Dokumentation .
Zum Beispiel könnte ich Folgendes tun:
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a / b (Upto 10 Decimal places and Round HALF_UP)
BigDecimal result = a.divide(b,10,RoundingMode.HALF_UP);
System.out.println(result);
Ergebnis: 0.7142857143
5.Reminder oder Modul
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a % b
BigDecimal result = a.remainder(b);
System.out.println(result);
Ergebnis: 5
6.Power
BigDecimal a = new BigDecimal("5");
//Equivalent to result = a^10
BigDecimal result = a.pow(10);
System.out.println(result);
Ergebnis: 9765625
7.Max
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = MAX(a,b)
BigDecimal result = a.max(b);
System.out.println(result);
Ergebnis: 7
8.Min
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = MIN(a,b)
BigDecimal result = a.min(b);
System.out.println(result);
Ergebnis: 5
9.Ziehpunkt nach links
BigDecimal a = new BigDecimal("5234.49843776");
//Moves the decimal point to 2 places left of current position
BigDecimal result = a.movePointLeft(2);
System.out.println(result);
Ergebnis: 52.3449843776
10.Ziehpunkt nach rechts
BigDecimal a = new BigDecimal("5234.49843776");
//Moves the decimal point to 3 places right of current position
BigDecimal result = a.movePointRight(3);
System.out.println(result);
Ergebnis: 5234498.43776
Es gibt viele weitere Optionen und Kombinationen von Parametern für die oben genannten Beispiele (z. B. gibt es 6 Variationen der Divide-Methode). Dieser Satz ist nicht erschöpfend und enthält einige grundlegende Beispiele.
Verwenden Sie BigDecimal anstelle von Float
Aufgrund der Darstellung des Float-Typs im Computerspeicher können die Ergebnisse von Operationen, die diesen Typ verwenden, ungenau sein - einige Werte werden als Näherungen gespeichert. Gute Beispiele dafür sind monetäre Berechnungen. Wenn eine hohe Präzision erforderlich ist, sollten andere Typen verwendet werden. zB bietet Java 7 BigDecimal.
import java.math.BigDecimal;
public class FloatTest {
public static void main(String[] args) {
float accountBalance = 10000.00f;
System.out.println("Operations using float:");
System.out.println("1000 operations for 1.99");
for(int i = 0; i<1000; i++){
accountBalance -= 1.99f;
}
System.out.println(String.format("Account balance after float operations: %f", accountBalance));
BigDecimal accountBalanceTwo = new BigDecimal("10000.00");
System.out.println("Operations using BigDecimal:");
System.out.println("1000 operations for 1.99");
BigDecimal operation = new BigDecimal("1.99");
for(int i = 0; i<1000; i++){
accountBalanceTwo = accountBalanceTwo.subtract(operation);
}
System.out.println(String.format("Account balance after BigDecimal operations: %f", accountBalanceTwo));
}
Ausgabe dieses Programms ist:
Operations using float:
1000 operations for 1.99
Account balance after float operations: 8009,765625
Operations using BigDecimal:
1000 operations for 1.99
Account balance after BigDecimal operations: 8010,000000
Für ein Startguthaben von 10000,00 nach 1000 Operationen für 1,99 erwarten wir, dass das Guthaben 8010,00 beträgt. Die Verwendung des Float-Typs gibt uns eine Antwort um 8009,77, was bei monetären Berechnungen unannehmbar ungenau ist. Die Verwendung von BigDecimal liefert das richtige Ergebnis.
BigDecimal.valueOf ()
Die BigDecimal-Klasse enthält einen internen Cache mit häufig verwendeten Nummern, z. B. 0 bis 10. Die BigDecimal.valueOf () -Methoden werden Konstruktoren mit ähnlichen Typparametern vorgezogen, dh im folgenden Beispiel wird a bevorzugt b.
BigDecimal a = BigDecimal.valueOf(10L); //Returns cached Object reference
BigDecimal b = new BigDecimal(10L); //Does not return cached Object reference
BigDecimal a = BigDecimal.valueOf(20L); //Does not return cached Object reference
BigDecimal b = new BigDecimal(20L); //Does not return cached Object reference
BigDecimal a = BigDecimal.valueOf(15.15); //Preferred way to convert a double (or float) into a BigDecimal, as the value returned is equal to that resulting from constructing a BigDecimal from the result of using Double.toString(double)
BigDecimal b = new BigDecimal(15.15); //Return unpredictable result
Initialisierung von BigDecimals mit dem Wert Null, Eins oder Zehn
BigDecimal bietet statische Eigenschaften für die Zahlen Null, Eins und Zehn. Es ist empfehlenswert, diese anstelle der tatsächlichen Zahlen zu verwenden:
Durch die Verwendung der statischen Eigenschaften vermeiden Sie eine unnötige Instantiierung. Außerdem enthält Ihr Code ein Literal anstelle einer 'magischen Zahl'.
//Bad example:
BigDecimal bad0 = new BigDecimal(0);
BigDecimal bad1 = new BigDecimal(1);
BigDecimal bad10 = new BigDecimal(10);
//Good Example:
BigDecimal good0 = BigDecimal.ZERO;
BigDecimal good1 = BigDecimal.ONE;
BigDecimal good10 = BigDecimal.TEN;