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

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;


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow