Java Academy · Lektion

Heltalsaritmetik og overflow

Forstå heltalsdivision, modulus, overflow-adfærd og hvordan De opdager det.

Lektion 2 af 413 trin

Heltalsaritmetik og overflow er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 2 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.

Heltalsaritmetik og overløb

Java-heltal har faste størrelser. Når en beregning overskrider den største eller mindste værdi, går resultatet lydløst rundt — der kastes ingen fejl. Hvis du forstår dette, kan du undgå subtile fejl.

Heltalsintervaller

Hver heltalstype har et begrænset interval, der bestemmes af dens bitbredde:

  • byte: -128 til 127
  • short: -32.768 til 32.767
  • int: -2.147.483.648 til 2.147.483.647
  • long: -9,2 × 10^18 til 9,2 × 10^18
System.out.println(Integer.MAX_VALUE); // 2147483647
System.out.println(Integer.MIN_VALUE); // -2147483648
System.out.println(Long.MAX_VALUE);    // 9223372036854775807
System.out.println(Byte.MAX_VALUE);    // 127

Overløb: Lydløs overgang

Hvis du lægger 1 til Integer.MAX_VALUE, går resultatet over til Integer.MIN_VALUE. Det er totalkomplementaritmetik — Java giver ingen garanti og kaster ingen fejl.

int max = Integer.MAX_VALUE;
System.out.println(max + 1); // -2147483648 (overflow!)

byte b = 127;
b++;  // wraps to -128
System.out.println(b); // -128

// Real bug: counting votes in a large election with int
int votes = Integer.MAX_VALUE;
votes += 100; // silently wrong
System.out.println(votes); // negative number!

Registrering af overløb med Math.addExact

Java 8+ introducerede Math.addExact(), multiplyExact() og subtractExact(), som kaster ArithmeticException ved overløb i stedet for lydløst at lade resultatet gå rundt.

try {
    int result = Math.addExact(Integer.MAX_VALUE, 1);
} catch (ArithmeticException e) {
    System.out.println("Overflow detected!"); // prints this
}

try {
    long safe = Math.multiplyExact(100_000L, 100_000L);
    System.out.println(safe); // 10000000000
} catch (ArithmeticException e) {
    System.out.println("Multiply overflow");
}

Heltalsdivision og modulo

Heltalsdivision afkortes mod nul. Operatoren % giver resten med samme fortegn som dividenden. Pas på division med nul — det kaster ArithmeticException.

System.out.println(10 / 3);    // 3 (not 3.33)
System.out.println(10 % 3);    // 1
System.out.println(-10 % 3);   // -1 (sign follows dividend)
System.out.println(-10 % -3);  // -1

try {
    int x = 5 / 0; // ArithmeticException: / by zero
} catch (ArithmeticException e) {
    System.out.println(e.getMessage()); // / by zero
}

// Float division by zero gives Infinity, not exception
System.out.println(5.0 / 0); // Infinity

long-aritmetik til store tal

Brug long, når værdier kan overskride int-intervallet. Tilføj altid L til long-literalværdier for at forhindre overløb før tildelingen.

// Bug: multiplication done as int, then widened
long wrong = 1_000_000 * 1_000_000;   // overflows int!
System.out.println(wrong); // -727379968 (wrong!)

// Fix: one operand is long
long correct = 1_000_000L * 1_000_000L;
System.out.println(correct); // 1000000000000

// Or cast first
long alsOk = (long) 1_000_000 * 1_000_000;
System.out.println(alsOk); // 1000000000000

Bitforskydningsoperatorer

Bitforskydningsoperatorer er hurtige måder at gange eller dividere med potenser af 2 på:

  • n << k — venstreforskydning: gang med 2^k
  • n >> k — fortegnet højreforskydning: dividér med 2^k
  • n >>> k — højreforskydning uden fortegn: udfylder med 0'er
int n = 8;
System.out.println(n << 1);  // 16 (8 * 2)
System.out.println(n << 2);  // 32 (8 * 4)
System.out.println(n >> 1);  // 4  (8 / 2)
System.out.println(n >> 2);  // 2  (8 / 4)

// Check if number is power of 2
boolean isPow2 = n > 0 && (n & (n - 1)) == 0;
System.out.println(isPow2); // true

Bitvis AND, OR og XOR

Bitvise operatorer arbejder på individuelle bit og bruges til tilladelser, flag og protokoller på lavt niveau.

int a = 0b1010; // 10
int b = 0b1100; // 12

System.out.println(Integer.toBinaryString(a & b)); // 1000 (AND = 8)
System.out.println(Integer.toBinaryString(a | b)); // 1110 (OR  = 14)
System.out.println(Integer.toBinaryString(a ^ b)); // 0110 (XOR = 6)
System.out.println(Integer.toBinaryString(~a));    // ...11110101 (NOT)

// Permission flags example
int READ  = 0b001;
int WRITE = 0b010;
int EXEC  = 0b100;
int perms = READ | WRITE; // user has read+write
System.out.println((perms & EXEC) != 0); // false — no exec

Understregninger i numeriske literaler

Java 7+ tillader understregninger i numeriske literaler for at gøre dem lettere at læse. Kompileren ignorerer dem.

int million = 1_000_000;
long creditCard = 4_111_1111_1111_1111L;
double pi = 3.141_592_653_589_793;
int hex = 0xFF_EC_D1_2E;
int binary = 0b0001_0101_0110;

System.out.println(million);   // 1000000
System.out.println(creditCard); // 4111111111111111

BigInteger til vilkårlig præcision

Når værdier overskrider long, skal du bruge BigInteger. Den har intet overløb, men er langsommere end primitive typer. Brug den til kryptografiske nøgler, fakulteter og astronomisk store tal.

import java.math.BigInteger;

BigInteger factorial100 = BigInteger.ONE;
for (int i = 2; i <= 100; i++) {
    factorial100 = factorial100.multiply(BigInteger.valueOf(i));
}
System.out.println(factorial100.toString().length() + " digits"); // 158 digits

BigInteger a = new BigInteger("999999999999999999999999999999");
BigInteger b = new BigInteger("1");
System.out.println(a.add(b)); // 1000000000000000000000000000000

Praktisk: Tæller, der håndterer overløb sikkert

Et mønster til at implementere en tæller, der håndterer overløb sikkert ved at bruge Math.addExact og falde tilbage til Long.MAX_VALUE.

class SafeCounter {
    private long count = 0;

    public void increment() {
        try {
            count = Math.addExact(count, 1L);
        } catch (ArithmeticException e) {
            count = Long.MAX_VALUE; // cap at max
        }
    }

    public long get() { return count; }
}

SafeCounter sc = new SafeCounter();
sc.increment();
sc.increment();
System.out.println(sc.get()); // 2

Hurtigt tjek

Hvad er værdien af følgende udtryk?

long result = 1_000_000 * 1_000_000;
System.out.println(result);

Opsummering: Heltalsaritmetik og overløb

Vigtigste pointer:

  • Heltalsoverløb går ubemærket i ring — ingen undtagelse som standard
  • Brug Math.addExact/multiplyExact/subtractExact til at registrere overløb
  • Heltalsdivision afkorter mod nul; tegnet for % følger dividenden
  • Brug literaler af typen long (suffikset L), når mellemresultater kan give overløb i int
  • BigInteger håndterer vilkårligt store værdier uden overløb
  • Bitforskydningsoperatorer er hurtige alternativer til multiplikation/division med potenser af 2
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 “Heltalsaritmetik og overflow” gratis?

Ja — hele teksten til “Heltalsaritmetik og overflow” 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 “Heltalsaritmetik og overflow”?

Forstå heltalsdivision, modulus, overflow-adfærd og hvordan De opdager det. 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 2 af 4.

Hvor lang tid tager lektionen “Heltalsaritmetik og overflow”?

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. Det grundlæggende om Math-klassen
  2. Heltalsaritmetik og overflow
  3. BigDecimal til økonomiske beregninger
  4. NumberFormat og printf
← Tilbage til Java Academy