BigDecimal for økonomiske beregninger
Bruk BigDecimal for å unngå presisjonsfeil med flyttall i penge- og skatteberegninger.
BigDecimal for økonomiske beregninger er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.
BigDecimal for finansielle beregninger
Flyttallstyper (double, float) kan ikke representere alle desimalverdier nøyaktig på grunn av binær representasjon. Bruk BigDecimal for penger og skatter.
Problemet med flyttall
Binære flyttall introduserer små avrundingsfeil. I finansielle apper akkumuleres disse feilene og fører til reelle feil.
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.9999999999999999Opprette BigDecimal på en trygg måte
Opprett alltid BigDecimal fra en String, ikke fra en double. Hvis du bruker double-konstruktøren, videreføres unøyaktigheten fra flyttall.
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.1Grunnleggende aritmetikk med BigDecimal
BigDecimal bruker metodekall til aritmetikk: add(), subtract(), multiply(), divide(). Disse returnerer nye BigDecimal-instanser (uforanderlige).
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.7676Avrundingsmoduser
RoundingMode styrer hvordan BigDecimal avrundes. Viktige moduser:
HALF_UP— standard avrunding (0.5 rundes opp)HALF_EVEN— bankavrunding (0.5 rundes til nærmeste partall)DOWN— forkast desimaldelen mot nullCEILING— rund mot positiv uendelighet
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.57Divisjon og skala
Divisjon med BigDecimal krever at du angir skala og avrundingsmodus for å unngå ArithmeticException ved uendelige desimalbrøker.
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.33Sammenligne BigDecimal-verdier
Bruk compareTo() til å sammenligne verdier, ikke equals(). equals() tar skala med i vurderingen — 2.0 og 2.00 er IKKE like med equals(), men ER like med 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 for signifikante sifre
MathContext angir presisjon (signifikante sifre) og avrundingsmodus. Bruk den når du trenger konsekvent presisjon i signifikante sifre i stedet for et bestemt antall desimalplasser.
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...Eksempel med handlekurv
En komplett beregning av en handlekurv med BigDecimal: varelinjer, skatt, rabatt og totalsum.
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
Betalingsformidlere som Stripe lagrer beløp som heltall i cent for å unngå desimalproblemer fullstendig. Konvertering mellom cent og beløp som skal vises, er et vanlig 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 bør du bruke BigDecimal fremfor double
Velg riktig type for oppgaven:
- BigDecimal: finansielle beløp, skatter og fakturaer, der nøyaktig desimalrepresentasjon er viktig
- double: vitenskapelige beregninger, grafikk og ML — der hastighet er viktig og små feil kan aksepteres
- int/long-cent: betalings-API-er og lagring av penger i databaser
Hurtigsjekk
Hvilken sammenligningsmetode for BigDecimal bør du bruke for å kontrollere om to BigDecimal-verdier er numerisk like, uavhengig av skala?
Oppsummering: BigDecimal for finansielle beregninger
Viktigste punkter:
- double/float fører til avrundingsfeil — bruk dem aldri for penger
- Opprett BigDecimal fra String eller BigDecimal.valueOf(), ikke fra double
- Bruk add(), subtract(), multiply() og divide() til aritmetikk
- Angi alltid skala og RoundingMode ved divisjon
- Bruk compareTo() til likhetssjekker, ikke equals()
- Vurder å lagre penger som heltall i cent ved arbeid med databaser og API-er
Lær deg Java med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 104
- Leksjoner
- 374
Ofte stilte spørsmål
Er leksjonen «BigDecimal for økonomiske beregninger» gratis?
Ja – hele teksten i «BigDecimal for økonomiske beregninger» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «BigDecimal for økonomiske beregninger»?
Bruk BigDecimal for å unngå presisjonsfeil med flyttall i penge- og skatteberegninger. Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Java Academy?
Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «BigDecimal for økonomiske beregninger»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?
Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Det viktigste om Math-klassen
- Heltallsaritmetikk og overflow
- BigDecimal for økonomiske beregninger
- NumberFormat og printf