Kokonaislukulaskenta ja ylivuoto
Ymmärrä kokonaislukujen jakolasku, jakojäännös, ylivuodon toiminta ja sen havaitseminen.
Kokonaislukulaskenta ja ylivuoto on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Kokonaislukuaritmetiikka ja ylivuoto
Java-kokonaisluvuilla on kiinteä koko. Kun laskutoimituksen tulos ylittää suurimman tai pienimmän mahdollisen arvon, se kiertyy hiljaisesti ympäri — poikkeusta ei heitetä. Tämän ymmärtäminen auttaa estämään vaikeasti havaittavia virheitä.
Kokonaislukujen arvoalueet
Jokaisella kokonaislukutyypillä on bittileveyden määrittämä rajattu arvoalue:
byte: -128–127short: -32,768–32,767int: -2,147,483,648–2,147,483,647long: -9.2 × 10^18–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); // 127Ylivuoto: hiljainen kiertyminen
Kun arvoon Integer.MAX_VALUE lisätään 1, tulokseksi tulee Integer.MIN_VALUE. Tämä on kahden komplementin aritmetiikkaa — Java ei ilmoita siitä eikä heitä poikkeusta.
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!Ylivuodon havaitseminen Math.addExact-metodilla
Java 8:ssa ja sitä uudemmissa versioissa esiteltiin Math.addExact()-, multiplyExact()- ja subtractExact()-metodit. Ne heittävät ArithmeticException-poikkeuksen ylivuodon sattuessa sen sijaan, että arvo kiertyisi hiljaisesti.
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");
}Kokonaislukujako ja jakojäännös
Kokonaislukujako katkaisee tuloksen kohti nollaa. %-operaattori antaa jakojäännöksen, jolla on jakajan sijaan jaettavan luvun etumerkki. Varo jakamista nollalla — se heittää ArithmeticException-poikkeuksen.
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); // InfinitySuurten lukujen laskeminen long-tyypillä
Käyttäkää long-tyyppiä, kun arvot voivat ylittää int-tyypin arvoalueen. Lisätkää aina L long-literaaleihin, jotta ylivuoto estetään ennen sijoittamista.
// 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); // 1000000000000Bittisiirto-operaattorit
Bittisiirto-operaattorit ovat nopea tapa kertoa tai jakaa kahden potensseilla:
n << k— vasemmalle siirto: kertominen luvulla 2^kn >> k— etumerkillinen oikealle siirto: jakaminen luvulla 2^kn >>> k— etumerkitön oikealle siirto: täyttää vasemmalta 0-biteillä
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); // trueBittikohtainen AND, OR ja XOR
Bittikohtaiset operaattorit käsittelevät yksittäisiä bittejä, ja niitä käytetään käyttöoikeuksissa, lipuissa ja matalan tason protokollissa.
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 execAlaviivat numeerisissa literaaleissa
Java 7:stä alkaen numeerisissa literaaleissa voi käyttää alaviivoja luettavuuden parantamiseksi. Kääntäjä jättää ne huomiotta.
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); // 4111111111111111BigInteger mielivaltaista tarkkuutta varten
Kun arvot ylittävät long-tyypin alueen, käyttäkää BigInteger-tyyppiä. Se ei aiheuta ylivuotoa, mutta on primitiivityyppejä hitaampi. Käyttäkää sitä salausavaimiin, kertomiin ja tähtitieteellisen suuriin lukuihin.
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)); // 1000000000000000000000000000000Käytännössä: ylivuototurvallinen laskuri
Malli sellaisen laskurin toteuttamiseen, joka käsittelee ylivuodot turvallisesti käyttämällä Math.addExact-menetelmää ja palaamalla tarvittaessa arvoon 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()); // 2Pikatarkistus
Mikä on seuraavan lausekkeen arvo?
long result = 1_000_000 * 1_000_000; System.out.println(result);
Kertaus: kokonaislukulaskenta ja ylivuoto
Keskeiset opit:
- Kokonaislukujen ylivuoto kiertyy huomaamatta – poikkeusta ei oletusarvoisesti heitetä
- Ylivuodon havaitsemiseen käyttäkää Math.addExact-, multiplyExact- ja subtractExact-menetelmiä
- Kokonaislukujako katkaisee tuloksen kohti nollaa; %-operaattorin merkki määräytyy jaettavan luvun mukaan
- Käyttäkää long-vakioita (L-pääte), kun välitulokset voivat aiheuttaa int-tyypin ylivuodon
- BigInteger käsittelee mielivaltaisen suuria arvoja ilman ylivuotoa
- Bittisiirto-operaattorit ovat nopeita vaihtoehtoja kahden potenssilla kertomiselle ja jakamiselle
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”Kokonaislukulaskenta ja ylivuoto” ilmainen?
Kyllä – oppitunnin ”Kokonaislukulaskenta ja ylivuoto” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Kokonaislukulaskenta ja ylivuoto”?
Ymmärrä kokonaislukujen jakolasku, jakojäännös, ylivuodon toiminta ja sen havaitseminen. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Kokonaislukulaskenta ja ylivuoto”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Math-luokan perusteet
- Kokonaislukulaskenta ja ylivuoto
- BigDecimal talouslaskennassa
- NumberFormat ja printf