0Pricing
Java Academy · Leçon

BigDecimal pour les calculs financiers

Utilisez BigDecimal pour éviter les erreurs de précision des nombres à virgule flottante dans les calculs monétaires et fiscaux.

BigDecimal pour les calculs financiers est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

BigDecimal pour les calculs financiers

Les types à virgule flottante (double, float) ne peuvent pas représenter exactement toutes les valeurs décimales en raison de leur représentation binaire. Pour l'argent et les taxes, utilisez BigDecimal.

Le problème des nombres à virgule flottante

La représentation binaire à virgule flottante introduit de minuscules erreurs d'arrondi. Dans les applications financières, ces erreurs s'accumulent et provoquent de véritables bogues.

double price = 0.1 + 0.2;
System.out.println(price);          // 0.30000000000000004 (WRONG!)
System.out.println(price == 0.3);   // false

// Real bug: total never equals expected
double total = 0;
for (int i = 0; i < 10; i++) total += 0.1;
System.out.println(total); // 0.9999999999999999

Créer BigDecimal en toute sécurité

Créez toujours BigDecimal à partir d'une String, et non d'un double. Utiliser le constructeur qui prend un double hérite de l'imprécision des nombres à virgule flottante.

import java.math.BigDecimal;

// WRONG: double constructor
BigDecimal wrong = new BigDecimal(0.1);
System.out.println(wrong); // 0.1000000000000000055511...

// CORRECT: String constructor
BigDecimal correct = new BigDecimal("0.1");
System.out.println(correct); // 0.1

// Or use valueOf (also safe)
BigDecimal safe = BigDecimal.valueOf(0.1);
System.out.println(safe); // 0.1

Arithmétique de base avec BigDecimal

BigDecimal utilise des appels de méthode pour les opérations arithmétiques : add(), subtract(), multiply(), divide(). Ces appels renvoient de nouvelles instances de BigDecimal (immuables).

import java.math.BigDecimal;

BigDecimal price = new BigDecimal("19.99");
BigDecimal tax   = new BigDecimal("0.08");
BigDecimal qty   = new BigDecimal("3");

BigDecimal subtotal = price.multiply(qty);
BigDecimal taxAmount = subtotal.multiply(tax);
BigDecimal total = subtotal.add(taxAmount);

System.out.println(subtotal);  // 59.97
System.out.println(taxAmount); // 4.7976
System.out.println(total);     // 64.7676

Modes d'arrondi

RoundingMode contrôle la manière dont BigDecimal arrondit. Principaux modes :

  • HALF_UP — arrondi standard (0,5 est arrondi vers le haut)
  • HALF_EVEN — arrondi bancaire (0,5 est arrondi vers le nombre pair le plus proche)
  • DOWN — tronque vers zéro
  • CEILING — arrondit vers l'infini positif
import java.math.*;

BigDecimal val = new BigDecimal("2.565");

System.out.println(val.setScale(2, RoundingMode.HALF_UP));   // 2.57
System.out.println(val.setScale(2, RoundingMode.HALF_EVEN)); // 2.56 (banker's)
System.out.println(val.setScale(2, RoundingMode.DOWN));      // 2.56
System.out.println(val.setScale(2, RoundingMode.CEILING));   // 2.57

Division et échelle

Une division avec BigDecimal nécessite de définir l'échelle et le mode d'arrondi afin d'éviter une ArithmeticException pour les nombres décimaux non terminés.

import java.math.*;

BigDecimal revenue = new BigDecimal("1000.00");
BigDecimal months  = new BigDecimal("3");

// Without scale → ArithmeticException (non-terminating decimal)
try {
    revenue.divide(months);
} catch (ArithmeticException e) {
    System.out.println("Need to specify scale!");
}

// Correct: specify scale and rounding
BigDecimal monthly = revenue.divide(months, 2, RoundingMode.HALF_UP);
System.out.println(monthly); // 333.33

Comparer des BigDecimals

Utilisez compareTo() pour comparer les valeurs, et non equals(). equals() tient compte de l'échelle : 2.0 et 2.00 sont NOT égaux selon equals(), mais ARE égaux selon compareTo().

import java.math.BigDecimal;

BigDecimal a = new BigDecimal("2.0");
BigDecimal b = new BigDecimal("2.00");

System.out.println(a.equals(b));        // false (different scale)
System.out.println(a.compareTo(b));     // 0 (same value)
System.out.println(a.compareTo(b) == 0); // true

// For sorting in collections
import java.util.*;
List<BigDecimal> prices = Arrays.asList(
    new BigDecimal("3.50"), new BigDecimal("1.00"), new BigDecimal("2.75")
);
Collections.sort(prices);
System.out.println(prices); // [1.00, 2.75, 3.50]

MathContext pour les chiffres significatifs

MathContext indique la précision (le nombre de chiffres significatifs) et le mode d'arrondi. Utilisez-le lorsque vous avez besoin d'une précision constante en chiffres significatifs plutôt qu'en nombre de décimales.

import java.math.*;

MathContext mc = new MathContext(4, RoundingMode.HALF_UP);

BigDecimal a = new BigDecimal("1234567");
BigDecimal b = new BigDecimal("3");

BigDecimal result = a.divide(b, mc);
System.out.println(result); // 4.115E+5 (4 significant digits)

// DECIMAL32, DECIMAL64, DECIMAL128 are standard MathContexts
BigDecimal precise = new BigDecimal("355").divide(
    new BigDecimal("113"), MathContext.DECIMAL64);
System.out.println(precise); // 3.141592920353982...

Exemple de panier

Calcul complet d'un panier d'achat avec BigDecimal : articles, taxe, remise et total final.

import java.math.*;

record LineItem(String name, BigDecimal price, int qty) {
    BigDecimal subtotal() {
        return price.multiply(new BigDecimal(qty));
    }
}

var items = List.of(
    new LineItem("Laptop",  new BigDecimal("999.00"), 1),
    new LineItem("Case",    new BigDecimal("29.99"),  2),
    new LineItem("Charger", new BigDecimal("49.99"),  1)
);

BigDecimal subtotal = items.stream()
    .map(LineItem::subtotal)
    .reduce(BigDecimal.ZERO, BigDecimal::add);

BigDecimal taxRate = new BigDecimal("0.09");
BigDecimal tax = subtotal.multiply(taxRate).setScale(2, RoundingMode.HALF_UP);
BigDecimal total = subtotal.add(tax);

System.out.println("Subtotal: " + subtotal);
System.out.println("Tax:      " + tax);
System.out.println("Total:    " + total);

Stripe : devise en centimes

Les processeurs de paiement comme Stripe stockent les montants sous forme de centimes entiers afin d'éliminer complètement les problèmes liés aux décimales. La conversion entre les centimes et les montants affichés est un modèle courant.

import java.math.*;

// Store as cents (long) for database / API
long amountCents = 999_99L; // $999.99

// Convert to BigDecimal for display
BigDecimal amount = BigDecimal
    .valueOf(amountCents)
    .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);

System.out.println("Amount: $" + amount); // Amount: $999.99

// Convert user input back to cents
BigDecimal input = new BigDecimal("49.95");
long cents = input.multiply(new BigDecimal("100"))
    .setScale(0, RoundingMode.HALF_UP).longValueExact();
System.out.println("Cents: " + cents); // Cents: 4995

Quand utiliser BigDecimal plutôt que double

Choisissez le type adapté à chaque usage :

  • BigDecimal : montants financiers, taxes et factures, lorsque la représentation décimale exacte est importante
  • double : calculs scientifiques, graphiques et apprentissage automatique, lorsque la vitesse compte et que de petites erreurs sont acceptables
  • int/long en centimes : API de paiement et stockage de l'argent en base de données

Vérification rapide

Quelle méthode de comparaison de BigDecimal devez-vous utiliser pour vérifier que deux valeurs BigDecimal sont numériquement égales, quelle que soit leur échelle ?

Récapitulatif : BigDecimal pour les calculs financiers

Points essentiels :

  • double et les nombres à virgule flottante provoquent des erreurs d'arrondi : ne les utilisez jamais pour l'argent
  • Créez BigDecimal à partir de String ou avec BigDecimal.valueOf(), et non à partir de double
  • Utilisez add(), subtract(), multiply() et divide() pour les opérations arithmétiques
  • Définissez toujours l'échelle et RoundingMode lors d'une division
  • Utilisez compareTo() pour tester l'égalité, et non equals()
  • Envisagez de stocker l'argent sous forme de centimes entiers pour les opérations sur les bases de données et les API

Questions Fréquemment Posées

La leçon « BigDecimal pour les calculs financiers » est-elle gratuite ?

Oui — le texte complet de « BigDecimal pour les calculs financiers » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « BigDecimal pour les calculs financiers » ?

Utilisez BigDecimal pour éviter les erreurs de précision des nombres à virgule flottante dans les calculs monétaires et fiscaux. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « BigDecimal pour les calculs financiers » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Les notions essentielles de la classe Math
  2. Arithmétique entière et dépassement de capacité
  3. BigDecimal pour les calculs financiers
  4. NumberFormat et printf
← Retour à Java Academy