Java Language
BigDecimal
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;