Java Academy · Lektion

Hvorfor ikke double til penge

Problemer med floating-point-præcision

Lektion 1 af 413 trin

Hvorfor ikke double til penge er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.

En farlig standard

Det føles naturligt at gemme priser i en double. Desværre kan double ikke repræsentere de fleste decimale brøker nøjagtigt, hvilket fører til små fejl, der ødelægger økonomiske beregninger.

Den klassiske overraskelse

Læg 0.1 og 0.2 sammen med double, så får du ikke 0.3. Du får en værdi med en lille afrundingsfejl.

public class Main {
    public static void main(String[] args) {
        double result = 0.1 + 0.2;
        System.out.println(result);
    }
}

Hvorfor det sker

Computere gemmer double binært. Ligesom en tredjedel ikke kan skrives nøjagtigt i decimalsystemet, kan mange decimaltal som 0.1 ikke skrives nøjagtigt binært.

Den nærmeste binære tilnærmelse gemmes, og fejlen akkumuleres.

Fejlene hober sig op

En enkelt lille fejl kan virke harmløs, men i en løkke, der gennemløber tusindvis af transaktioner, akkumuleres forskellene til synlige fejl.

public class Main {
    public static void main(String[] args) {
        double total = 0.0;
        for (int i = 0; i < 10; i++) {
            total += 0.1;
        }
        System.out.println(total);
    }
}

Når lighedssammenligningen fejler

På grund af afrundingsfejl mislykkes det ofte at sammenligne beregnede double-værdier med ==, når du forventer, at de er ens.

public class Main {
    public static void main(String[] args) {
        double a = 0.1 + 0.2;
        double b = 0.3;
        System.out.println(a == b);
    }
}

Penge kræver nøjagtighed

I finansverdenen er en fejl på en brøkdel af en øre uacceptabel. Revisorer forventer, at totalerne stemmer ned til sidste øre.

Derfor bør penge aldrig gemmes som en flydende kommatype.

Løsningen: BigDecimal

Java tilbyder BigDecimal, en klasse, der gemmer decimaltal nøjagtigt. Den holder den uskalerede værdi og skalaen separat, så 0.1 virkelig betyder 0.1.

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("0.1");
        BigDecimal b = new BigDecimal("0.2");
        System.out.println(a.add(b));
    }
}

Brug altid String-konstruktøren

Opret en BigDecimal ud fra en String, ikke ud fra en double. Hvis du sender en double, overføres den binære fejl til BigDecimal.

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal fromDouble = new BigDecimal(0.1);
        BigDecimal fromString = new BigDecimal("0.1");
        System.out.println(fromDouble);
        System.out.println(fromString);
    }
}

Eller brug valueOf

BigDecimal.valueOf er en sikker genvej. Den konverterer double-værdien ved hjælp af dens kanoniske strengrepræsentation, så den rå binære fejl undgås.

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal price = BigDecimal.valueOf(19.99);
        System.out.println(price);
    }
}

Gem beløb i øre

Et alternativ i enkle tilfælde er at gemme beløb som et heltal, der angiver antal øre, ved hjælp af long. Så bliver 19,99 dollars til 1999 øre, og al matematik er nøjagtig heltalsmatematik.

public class Main {
    public static void main(String[] args) {
        long cents = 1999;
        long total = cents * 3;
        System.out.println(total + " cents");
    }
}

Hovedpointen

Brug float og double til videnskabelige beregninger og grafikarbejde, hvor små fejl er acceptable. Til penge og alle værdier, der skal være nøjagtige, skal du bruge BigDecimal eller hele antal øre.

Kort test

Test din forståelse af præcision med flydende komma.

Opsummering

Du har lært, hvorfor double ikke fungerer til penge:

  • Binær flydende kommanotation kan ikke gemme mange decimaltal nøjagtigt
  • Fejl som at 0.1 + 0.2 ikke er lig med 0.3, ophobes
  • Brug BigDecimal til nøjagtig decimalregning
  • Opret den ud fra en String eller med valueOf, aldrig ud fra en rå double
  • Det er også muligt at gemme hele antal øre nøjagtigt
Gratis at komme i gang

Lær Java med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
104
Lektioner
374

Ofte stillede spørgsmål

Er lektionen “Hvorfor ikke double til penge” gratis?

Ja — hele teksten til “Hvorfor ikke double til penge” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Hvorfor ikke double til penge”?

Problemer med floating-point-præcision Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Java Academy?

Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Hvorfor ikke double til penge”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Java Academy-lektion?

Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Hvorfor ikke double til penge
  2. Arbejd med BigDecimal
  3. Afrunding og scale
  4. BigInteger til enorme tal
← Tilbage til Java Academy