Java Academy · Lektion

Heltalsaritmetik och spill

Förstå heltalsdivision, modulo, spillbeteende och hur ni upptäcker spill.

Lektion 2 av 413 steg

Heltalsaritmetik och spill är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 2 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.

Heltalsaritmetik och overflow

Java-heltal har fasta storlekar. När en beräkning överskrider det största eller minsta värdet uppstår ett tyst overflow – inget undantag kastas. Att förstå detta förebygger svårupptäckta fel.

Heltalsintervall

Varje heltalstyp har ett begränsat intervall som bestäms av bitbredden:

  • byte: -128 till 127
  • short: -32,768 till 32,767
  • int: -2,147,483,648 till 2,147,483,647
  • long: -9.2 × 10^18 till 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

Overflow: tyst omslag

Att lägga till 1 till Integer.MAX_VALUE gör att värdet slår om till Integer.MIN_VALUE. Detta är tvåkomplementaritmetik – Java ger ingen garanti och kastar inget undantag.

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!

Upptäcka overflow med Math.addExact

Java 8+ introducerade Math.addExact(), multiplyExact() och subtractExact(), som kastar ArithmeticException vid overflow i stället för att tyst slå runt.

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 och restoperator

Heltalsdivision trunkeras mot noll. Operatorn % ger resten med samma tecken som dividenden. Se upp med division med noll – det kastar 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 för stora tal

Använd long när värden kan överskrida int-intervallet. Lägg alltid till L i long-literaler för att förhindra overflow före tilldelningen.

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

Bitförskjutningsoperatorer

Bitförskjutningsoperatorer är snabba sätt att multiplicera eller dividera med potenser av 2:

  • n << k – vänsterförskjutning: multiplicera med 2^k
  • n >> k – signerad högerförskjutning: dividera med 2^k
  • n >>> k – osignerad högerförskjutning: fyller på med 0:or
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

Bitvisa AND, OR och XOR

Bitvisa operatorer arbetar med enskilda bitar och används för behörigheter, flaggor och lågnivåprotokoll.

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

Understreck i numeriska literaler

Java 7+ tillåter understreck i numeriska literaler för att förbättra läsbarheten. Kompilatorn ignorerar 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 för godtycklig precision

När värden överskrider long används BigInteger. Det har inget overflow men är långsammare än primitiva datatyper. Använd det för kryptografiska nycklar, fakulteter och astronomiskt stora 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

Praktiskt: Overflow-säker räknare

Ett mönster för att implementera en räknare som hanterar overflow säkert genom att använda Math.addExact och falla tillbaka till 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

Snabbkontroll

Vilket värde får följande uttryck?

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

Sammanfattning: heltalsaritmetik och overflow

Viktiga slutsatser:

  • Heltalsöverflöde slår runt tyst – inget undantag som standard
  • Använd Math.addExact/multiplyExact/subtractExact för att upptäcka overflow
  • Heltalsdivision trunkerar mot noll; tecknet för % följer dividenden
  • Använd long-litteraler (suffixet L) när mellanresultat kan orsaka overflow för int
  • BigInteger hanterar godtyckligt stora värden utan overflow
  • Bitförskjutningsoperatorer är snabba alternativ till multiplikation och division med tvåpotenser
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 ”Heltalsaritmetik och spill” gratis?

Ja – hela texten till ”Heltalsaritmetik och spill” 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 ”Heltalsaritmetik och spill”?

Förstå heltalsdivision, modulo, spillbeteende och hur ni upptäcker spill. 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 2 av 4.

Hur lång tid tar lektionen ”Heltalsaritmetik och spill”?

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