Java Language
BigDecimal
Sök…
Introduktion
BigDecimal- klassen tillhandahåller operationer för aritmetik (lägg till, subtrahera, multiplicera, dela), skala manipulation, avrundning, jämförelse, hashing och formatkonvertering. BigDecimal representerar oföränderligt, godtyckligt preciserat decimaltal. Denna klass ska användas för att beräkna hög precision.
BigDecimal-objekt är oföränderliga
Om du vill beräkna med BigDecimal måste du använda det returnerade värdet eftersom BigDecimal-objekt är oföränderliga:
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
Jämför BigDecimals
Metoden compareTo
bör användas för att jämföra 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
Vanligtvis bör du inte använda metoden equals
eftersom den anser att två BigDecimals
endast är lika om de är lika i värde och också skala :
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
Matematiska operationer med BigDecimal
Detta exempel visar hur du utför grundläggande matematiska operationer med hjälp av BigDecimals.
1.Addition
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a + b
BigDecimal result = a.add(b);
System.out.println(result);
Resultat: 12
2.Subtraction
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
//Equivalent to result = a - b
BigDecimal result = a.subtract(b);
System.out.println(result);
Resultat: -2
3.Multiplication
När man multiplicerar två BigDecimal
resultatet att ha skala lika med summan av skalorna på operander.
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);
Resultat: 36.89931
För att ändra resultatets skala använder du den överbelastade multiplikationsmetoden som gör det möjligt att passera MathContext
- ett objekt som beskriver reglerna för operatörer, särskilt resultatets precision och avrundningsläge. För mer information om tillgängliga avrundningslägen, se Oracle-dokumentationen.
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);
Resultat: 36,90
4.Division
Uppdelning är lite mer komplicerad än de andra aritmetiska operationerna, tänk exempelvis nedanstående exempel:
BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");
BigDecimal result = a.divide(b);
System.out.println(result);
Vi förväntar oss att detta skulle ge något som liknar: 0.7142857142857143, men vi skulle få:
Resultat: java.lang.ArithmeticException: Icke avslutande decimalutvidgning; inget exakt representativt decimalresultat.
Detta skulle fungera perfekt när resultatet skulle bli en avslutande decimal säga om jag ville dela 5 med 2, men för de siffror som vid delning skulle ge ett icke avslutande resultat skulle vi få en ArithmeticException
. I den verkliga scenariot kan man inte förutsäga de värden som skulle uppstå under uppdelningen, så vi måste specificera skalan och avrundningsläget för BigDecimal-divisionen. Mer information om skala och avrundningsläge finns i Oracle-dokumentationen .
Till exempel kan jag göra:
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);
Resultat: 0.7142857143
5. Rest eller 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);
Resultat: 5
6.Power
BigDecimal a = new BigDecimal("5");
//Equivalent to result = a^10
BigDecimal result = a.pow(10);
System.out.println(result);
Resultat: 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);
Resultat: 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);
Resultat: 5
9. Flytta pekar till vänster
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);
Resultat: 52.3449843776
10. Flytta pekar till höger
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);
Resultat: 5234498.43776
Det finns många fler alternativ och kombination av parametrar för ovan nämnda exempel (till exempel finns det 6 varianter av delningsmetoden), denna uppsättning är en icke uttömmande lista och täcker några grundläggande exempel.
Använda BigDecimal istället för float
På grund av att flottörtypen representeras i datorminne kan resultat av operationer som använder denna typ vara felaktiga - vissa värden lagras som ungefärliga. Bra exempel på detta är monetära beräkningar. Om hög precision är nödvändig bör andra typer användas. t.ex. Java 7 tillhandahåller 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));
}
Output från detta program är:
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 en startbalans på 10000,00, efter 1000 operationer för 1,99, förväntar vi oss att saldot blir 8010,00. Användning av flottörtypen ger oss ett svar på cirka 8009,77, vilket är oacceptabelt upresist när det gäller monetära beräkningar. Att använda BigDecimal ger oss rätt resultat.
BigDecimal.valueOf ()
BigDecimal-klassen innehåller en intern cache av ofta använda siffror, t.ex. 0 till 10. BigDecimal.valueOf () -metoderna tillhandahålls företrädesvis för konstruktörer med parametrar av liknande typ, dvs i exemplet nedan föredras a 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
Initialisering av BigDecimals med värdet noll, en eller tio
BigDecimal tillhandahåller statiska egenskaper för siffrorna noll, en och tio. Det är bra att använda dessa istället för att använda de faktiska siffrorna:
Genom att använda de statiska egenskaperna undviker du en onödig instans, du har också en bokstavlig kod i stället för ett "magiskt nummer".
//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;