BigDecimal för finansiella beräkningar
Använd BigDecimal för att undvika precisionfel med flyttal vid beräkningar av pengar och skatter.
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.9999999999999999Skapa 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.1Grundlä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.7676Avrundningslä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 nollCEILING— 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.57Division 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.33Jä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: 4995Nä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
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
- Grunderna i klassen Math
- Heltalsaritmetik och spill
- BigDecimal för finansiella beräkningar
- NumberFormat och printf