Recherche…


Introduction

La classe BigDecimal fournit des opérations pour l'arithmétique (ajouter, soustraire, multiplier, diviser), la manipulation d'échelle, l'arrondissement, la comparaison, le hachage et la conversion de format. Le BigDecimal représente des nombres décimaux signés, immuables et de précision arbitraire. Cette classe doit être utilisée pour effectuer un calcul de haute précision.

Les objets BigDecimal sont immuables

Si vous voulez calculer avec BigDecimal, vous devez utiliser la valeur renvoyée car les objets BigDecimal sont immuables:

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 

Comparer les BigDecimals

La méthode compareTo doit être utilisée pour comparer 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

Généralement, vous ne devriez pas utiliser la méthode des equals , car elle considère que deux BigDecimals égaux seulement s'ils sont égaux en valeur et aussi en échelle :

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

Opérations mathématiques avec BigDecimal

Cet exemple montre comment effectuer des opérations mathématiques de base en utilisant 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);

Résultat: 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);

Résultat: -2

3. Multiplication

En multipliant deux BigDecimal le résultat aura une échelle égale à la somme des échelles des opérandes.

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

Résultat: 36.89931

Pour changer l'échelle du résultat, utilisez la méthode de multiplication surchargée qui permet de passer MathContext - un objet décrivant les règles pour les opérateurs, en particulier la précision et le mode d'arrondi du résultat. Pour plus d'informations sur les modes d'arrondi disponibles, reportez-vous à la documentation 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);

Résultat: 36.90

4.Division

La division est un peu plus compliquée que les autres opérations arithmétiques, par exemple prenons l'exemple ci-dessous:

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

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

Nous nous attendrions à ce que cela donne quelque chose de similaire à: 0.7142857142857143, mais nous aurions:

Résultat: java.lang.ArithmeticException: expansion décimale non terminante; aucun résultat décimal représentable exact.

Cela fonctionnerait parfaitement lorsque le résultat serait un nombre décimal final si je voulais diviser 5 par 2, mais pour les nombres qui, en se divisant, donneraient un résultat non final, nous aurions une ArithmeticException . Dans le scénario réel, on ne peut pas prédire les valeurs qui seraient rencontrées pendant la division. Nous devons donc spécifier l’ échelle et le mode d’arrondi pour la division BigDecimal. Pour plus d'informations sur le mode Scale et Rounding, reportez-vous à la documentation Oracle .

Par exemple, je pourrais faire:

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

Résultat: 0.7142857143

5. Reste ou module

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

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

Résultat: 5

6. puissance

BigDecimal a = new BigDecimal("5");

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

Résultat: 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);

Résultat: 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);

Résultat: 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);

Résultat: 52.3449843776

10.Move Point To Right

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

Résultat: 5234498.43776

Il y a beaucoup plus d'options et de combinaisons de paramètres pour les exemples mentionnés ci-dessus (par exemple, il existe 6 variantes de la méthode de division), cet ensemble est une liste non exhaustive et couvre quelques exemples de base.

Utiliser BigDecimal au lieu de float

En raison de la représentation du type float dans la mémoire de l'ordinateur, les résultats des opérations utilisant ce type peuvent être inexacts - certaines valeurs sont stockées sous forme d'approximations. Les calculs monétaires en sont de bons exemples. Si une haute précision est nécessaire, d'autres types doivent être utilisés. Par exemple, Java 7 fournit 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));
}

Le résultat de ce programme est:

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

Pour un solde initial de 10 000,00, après 1 000 opérations pour 1,99, le solde devrait être de 8010,00. L'utilisation du type float nous donne une réponse autour de 8009.77, ce qui est très imprécis dans le cas des calculs monétaires. L'utilisation de BigDecimal nous donne le bon résultat.

BigDecimal.valueOf ()

La classe BigDecimal contient un cache interne des nombres fréquemment utilisés, par exemple 0 à 10. Les méthodes BigDecimal.valueOf () sont préférables aux constructeurs avec des paramètres de type similaires, c'est-à-dire que l'exemple ci-dessous est préférable à 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

Initialisation de BigDecimals avec la valeur zéro, un ou dix

BigDecimal fournit des propriétés statiques pour les nombres zéro, un et dix. Il est recommandé de les utiliser plutôt que d'utiliser les nombres réels:

En utilisant les propriétés statiques, vous évitez une instanciation inutile, vous avez également un littéral dans votre code au lieu d'un «nombre magique».

//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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow