Ricerca…


introduzione

La classe BigDecimal fornisce operazioni per l'aritmetica (addizione, sottrazione, moltiplicazione, divisione), manipolazione della scala, arrotondamento, confronto, hashing e conversione del formato. Il BigDecimal rappresenta i numeri decimali firmati immutabili, con precisione arbitraria. Questa classe deve essere utilizzata in una necessità di calcolo ad alta precisione.

Gli oggetti BigDecimal sono immutabili

Se vuoi calcolare con BigDecimal devi usare il valore restituito perché gli oggetti BigDecimal sono immutabili:

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 

Confronto di BigDecimals

Il metodo compareTo dovrebbe essere usato per confrontare 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

Comunemente non si dovrebbe usare il equals metodo in quanto considera due BigDecimals uguali solo se sono uguali in valore e anche scala:

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

Operazioni matematiche con BigDecimal

Questo esempio mostra come eseguire operazioni matematiche di base usando 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);

Risultato: 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);

Risultato: -2

3.Multiplication

Quando si moltiplicano due BigDecimal , il risultato avrà una scala uguale alla somma delle scale degli operandi.

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);

Risultato: 36.89931

Per modificare la scala del risultato utilizzare il metodo di moltiplicazione sovraccarico che consente di passare MathContext , un oggetto che descrive le regole per gli operatori, in particolare la precisione e la modalità di arrotondamento del risultato. Per ulteriori informazioni sulle modalità di arrotondamento disponibili, consultare la documentazione Oracle.

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);

Risultato: 36.90

4.Division

La divisione è un po 'più complicata delle altre operazioni aritmetiche, ad esempio si consideri l'esempio seguente:

BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");

BigDecimal result = a.divide(b);
System.out.println(result);

Ci aspettiamo che questo dia qualcosa di simile a: 0.7142857142857143, ma otterremmo:

Risultato: java.lang.ArithmeticException: espansione decimale senza terminazione; nessun risultato decimale rappresentabile esatto.

Ciò funzionerebbe perfettamente quando il risultato sarebbe un decimale terminante dire se volessi dividere 5 per 2, ma per quei numeri che al momento della divisione darebbero un risultato non terminante otterremmo una ArithmeticException . Nello scenario del mondo reale, non è possibile prevedere i valori che verrebbero rilevati durante la divisione, quindi è necessario specificare la scala e la modalità di arrotondamento per la divisione BigDecimal. Per ulteriori informazioni sulla modalità di scala e arrotondamento, consultare la documentazione Oracle .

Ad esempio, potrei fare:

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);

Risultato: 0,7142857143

5. Remainder o modulo

BigDecimal a = new BigDecimal("5");
BigDecimal b = new BigDecimal("7");

//Equivalent to result = a % b
BigDecimal result = a.remainder(b);
System.out.println(result);

Risultato: 5

6.Power

BigDecimal a = new BigDecimal("5");

//Equivalent to result = a^10    
BigDecimal result = a.pow(10);
System.out.println(result);

Risultato: 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);

Risultato: 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);

Risultato: 5

9.Move Point To Left

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);

Risultato: 52.3449843776

10. Spostare il punto verso destra

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);

Risultato: 5234498.43776

Ci sono molte più opzioni e combinazioni di parametri per gli esempi sopra citati (ad esempio, ci sono 6 varianti del metodo di divisione), questo insieme è un elenco non esaustivo e copre alcuni esempi di base.

Utilizzo di BigDecimal anziché float

A causa del modo in cui il tipo float è rappresentato nella memoria del computer, i risultati delle operazioni che utilizzano questo tipo possono essere inaccurati - alcuni valori sono memorizzati come approssimazioni. Buoni esempi di questo sono i calcoli monetari. Se è necessaria un'elevata precisione, è necessario utilizzare altri tipi. ad es. Java 7 fornisce 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));
}

L'output di questo programma è:

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

Per un saldo iniziale di 10000,00, dopo 1000 operazioni per 1,99, ci aspettiamo che il saldo sia 8010,00. L'uso del tipo float ci fornisce una risposta intorno a 8009,77, che è inaccettabilmente imprecisa nel caso di calcoli monetari. Usando BigDecimal ci dà il risultato corretto.

BigDecimal.valueOf ()

La classe BigDecimal contiene una cache interna di numeri utilizzati frequentemente, ad esempio da 0 a 10. I metodi BigDecimal.valueOf () vengono forniti preferibilmente a costruttori con parametri di tipo simili, ovvero nell'esempio sotto a è preferito 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

Inizializzazione di BigDecimals con valore zero, uno o dieci

BigDecimal fornisce proprietà statiche per i numeri zero, uno e dieci. È buona norma utilizzare questi invece dei numeri effettivi:

Usando le proprietà statiche, si evita un'istanza non necessaria, inoltre si ha un letterale nel codice anziché un "numero magico".

//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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow