Java Academy · Lektion

BigDecimal för finansiella beräkningar

Använd BigDecimal för att undvika precisionfel med flyttal vid beräkningar av pengar och skatter.

Lektion 3 av 413 steg

BigDecimal för finansiella beräkningar är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.

BigDecimal för ekonomiska beräkningar

Flyttalstyper (double, float) kan inte representera alla decimaltal exakt på grund av den binära representationen. Använd BigDecimal för pengar och skatter.

Problemet med flyttal

Binära flyttal introducerar små avrundningsfel. I ekonomiska program ackumuleras dessa fel och orsakar verkliga buggar.

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

Skapa BigDecimal på ett säkert sätt

Skapa alltid BigDecimal från en String, inte från en double. Konstruktoranropet med double ärver flyttalets inexakthet.

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

Grundläggande aritmetik med BigDecimal

BigDecimal använder metodanrop för aritmetik: add(), subtract(), multiply(), divide(). Dessa returnerar nya BigDecimal-instanser (oföränderliga).

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

Avrundningslägen

RoundingMode styr hur BigDecimal avrundas. Viktiga lägen:

  • HALF_UP — standardavrundning (0.5 avrundas uppåt)
  • HALF_EVEN — bankavrundning (0.5 avrundas till närmaste jämna tal)
  • DOWN — trunkera mot noll
  • CEILING — avrunda mot positiv oändlighet
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 och skala

Division med BigDecimal kräver att skala och avrundningsläge anges för att undvika ArithmeticException vid icke-avslutande decimaler.

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

Jämföra BigDecimal-värden

Använd compareTo() för att jämföra värden, inte equals(). equals() tar hänsyn till skalan — 2.0 och 2.00 är INTE lika enligt equals(), men ÄR lika enligt 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 för signifikanta siffror

MathContext anger precision (signifikanta siffror) och avrundningsläge. Använd det när du behöver en konsekvent precision i signifikanta siffror i stället för ett visst antal decimaler.

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...

Exempel: kundvagn

En fullständig beräkning av en kundvagn med BigDecimal: radposter, skatt, rabatt och slutsumma.

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: valuta i cent

Betalningsförmedlare som Stripe lagrar belopp som hela cent för att helt undvika decimalproblem. Omvandling mellan cent och belopp för visning är ett vanligt mönster.

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

När ska BigDecimal användas i stället för double?

Välj rätt typ för uppgiften:

  • BigDecimal: ekonomiska belopp, skatter och fakturor, där exakt decimalrepresentation är viktig
  • double: vetenskapliga beräkningar, grafik och ML – där snabbhet är viktig och små fel kan accepteras
  • int/long i cent: betalnings-API:er och databaslagring av pengar

Snabbkontroll

Vilken BigDecimal-jämförelsemetod ska du använda för att kontrollera om två BigDecimal-värden är numeriskt lika, oavsett skala?

Sammanfattning: BigDecimal för ekonomiska beräkningar

Viktiga slutsatser:

  • double/float orsakar avrundningsfel – använd dem aldrig för pengar
  • Skapa BigDecimal från String eller BigDecimal.valueOf(), inte från double
  • Använd add(), subtract(), multiply() och divide() för aritmetik
  • Ange alltid skala och RoundingMode vid division
  • Använd compareTo() för likhetskontroller, inte equals()
  • Överväg att lagra pengar som hela cent vid databas- och API-arbete
Gratis att börja

Lär dig Java med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
104
Lektioner
374

Vanliga frågor

Är lektionen ”BigDecimal för finansiella beräkningar” gratis?

Ja – hela texten till ”BigDecimal för finansiella beräkningar” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”BigDecimal för finansiella beräkningar”?

Använd BigDecimal för att undvika precisionfel med flyttal vid beräkningar av pengar och skatter. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Java Academy?

Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”BigDecimal för finansiella beräkningar”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Java Academy-lektionen?

Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Grunderna i klassen Math
  2. Heltalsaritmetik och spill
  3. BigDecimal för finansiella beräkningar
  4. NumberFormat och printf
← Tillbaka till Java Academy