Primitív típus | Méret a memóriában | Értéktartomány |
---|---|---|
byte | 8 bites | -128-127 |
rövid | 16 bites | -32768-32767 |
char | 16 bites | 0-tól 65536-ig |
int | 32 bites | -2147483648-2147483647 |
hosszú | 64 bites | -9223372036854775808-9223372036854775807 |
úszó | 32 bites | (2-től -149 hatványáig) ((2-től -23 hatványáig) * 2-től 127 hatványáig) |
kettős | 64 bites | (-2 a 63 hatványához) - ((2 a 63 hatványához) - 1) |
logikai érték | 8 (ha tömbökben használják), 32 (ha nem tömbben használják) | igaz vagy hamis |
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigDecimal decimal = new BigDecimal("123.444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444");
System.out.println(decimal);
}
}
Egy karakterlánc átadása a konstruktornak csak egy lehetséges lehetőség. Itt karakterláncokat használunk, mert a számaink meghaladják a long és a double maximális értékét , és el kell magyaráznunk a fordítónak, hogy melyik számot szeretnénk létrehozni :) 1111111111111111111111111111111111111111111111111111111111111111111111111111 a konstruktorhoz nem fog működni: a Java megpróbálja belezsúfolni az átadott számot valamelyik primitív adattípusba, de egyikbe sem fér bele. Ezért jó megoldás egy karakterlánc használata a kívánt szám átadására. Mindkét osztály képes automatikusan számértékeket kinyerni az átadott karakterláncokból. Egy másik fontos szempont, amelyet meg kell jegyeznünk, amikor nagyszámú osztályokkal dolgozunk, az az, hogy objektumaik megváltoztathatatlanok ( Immutable ). A String osztály és a primitív típusok (Integer, Long stb.) wrapper osztályaival kapcsolatos tapasztalatainak köszönhetően már ismeri a megváltoztathatatlanságot .
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
integer.add(BigInteger.valueOf(33333333));
System.out.println(integer);
}
}
Konzol kimenet:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Ahogy az várható volt, számunk nem változott. Az összeadási művelet végrehajtásához létre kell hoznia egy új objektumot, amely megkapja a művelet eredményét.
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
System.out.println(integer);
BigInteger result = integer.add(BigInteger.valueOf(33333333));
System.out.println(result);
}
}
Konzol kimenet:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111144444444
Na látod, most már minden úgy működik, ahogy kell :) Egyébként észrevetted, milyen szokatlanul néz ki az összeadási művelet?
BigInteger result = integer.add(BigInteger.valueOf(33333333));
Ez egy másik fontos szempont. A nagyszámú osztályok nem használják a + - * / operátorokat. Ehelyett módszereket kínálnak. Ismerkedjünk meg a főbbekkel (mint mindig, a módszerek teljes listáját az Oracle dokumentációjában találod: itt és itt ).
-
metódusok az aritmetikai műveletekhez: összeadás() , kivonás() , szorzás() , osztás() . Ezeket a módszereket az összeadás, kivonás, szorzás és osztás végrehajtására használják.
-
doubleValue() , intValue() , floatValue() , longValue() stb. a nagy számok Java primitív típusaivá alakítására szolgál. Legyen óvatos, amikor ezeket a módszereket használja. Ne feledkezzünk meg a bitméret különbségeiről sem!
import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); long result = integer.longValue(); System.out.println(result); } }
Konzol kimenet:
8198552921648689607
-
A min() és max() segítségével megtalálhatja két nagy szám minimális és maximális értékét.
Vegye figyelembe, hogy ezek a módszerek nem statikusak!import java.math.BigInteger; public class Main { public static void main(String[] args) { BigInteger integer = new BigInteger("11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"); BigInteger integer2 = new BigInteger("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"); System.out.println(integer.max(integer2)); } }
Konzol kimenet:
222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
BigDecimális kerekítési viselkedés
Ennek a témának külön szakasza van, mivel a nagy számok kerekítése és a kerekítési viselkedés beállítása nem olyan egyszerű. A setScale() metódussal beállíthatja a BigDecimal tizedesjegyeinek számát . Tegyük fel például, hogy azt szeretnénk, hogy a 111.5555555555 szám három számjegyből álljon a tizedesvessző után. Azonban nem érhetjük el, amit akarunk, ha a 3-as számot argumentumként adjuk át a setScale() metódusnak. Mint fentebb említettük, BigDecimalszámok ábrázolására szolgál, szigorú számítási pontossági követelményekkel. Jelenlegi formájában a számunk 10 számjegyből áll a tizedesvessző után. Ebből 7-et szeretnénk eldobni, és csak 3-at szeretnénk megtartani. Ennek megfelelően a 3-as szám mellett át kell lépnünk a kerekítési módot is. A BigDecimal összesen 8 kerekítési móddal rendelkezik. Az sok! De ha valóban finomítania kell a számítások pontosságát, akkor minden megvan, amire szüksége van. Tehát itt van a BigDecimal által kínált 8 kerekítési mód :-
ROUND_CEILING – felfelé kerekít
111.5555555555 -> setScale(3, ROUND_CEILING) -> 111.556
-
ROUND_DOWN – nulla felé kerekít
111.5555555555 -> setScale(3, ROUND_DOWN) -> 111.555
-
ROUND_FLOOR – lefelé kerekít
111.5555555555 -> setScale(3, ROUND_FLOOR) -> 111.555
-
ROUND_HALF_UP — felfelé kerekít, ha a tizedesvessző utáni szám >= 0,5
0.55 -> setScale(1, ROUND_HALF_UP) -> 0.6 0.54 -> setScale(1, ROUND_HALF_UP) -> 0.5
-
ROUND_HALF_DOWN – felfelé kerekít, ha a tizedesvessző utáni szám > 0,5
0.55 -> setScale(1, ROUND_HALF_DOWN) -> 0.5 0.56 -> setScale(1, ROUND_HALF_DOWN) -> 0.6
-
ROUND_HALF_EVEN — a kerekítés a tizedesvesszőtől balra lévő számtól függ. Ha a bal oldali szám páros, a kerekítés lefelé történik. Ha a tizedesvesszőtől balra lévő szám páratlan, akkor a kerekítés felfelé történik.
2.5 -> setScale(0, ROUND_HALF_EVEN) -> 2
A tizedesjegytől balra lévő szám 2 (páros). A szám lefelé kerekítve. 0 tizedesjegyet akarunk, így az eredmény 2.
3.5 -> setScale(0, ROUND_HALF_EVEN) -> 4
A tizedesvesszőtől balra lévő szám 3 (páratlan). A szám felfelé kerekítve. 0 tizedesjegyet akarunk, így az eredmény 4.
-
ROUND_UNNECCESSARY — Ez a mód akkor használatos, ha kerekítési módot kell átadnia egy metódusnak, de a számot nem kell kerekíteni. Ha megpróbál kerekíteni egy számot a ROUND_UNNECCESSARY móddal, akkor a rendszer egy Aritmetikai kivételt dob fel.
3.51 -> setScale(1, ROUND_UNNECCESSARY) -> ArithmeticException
-
ROUND_UP – kerekítés a nulláról.
111.5551 -> setScale(3, ROUND_UP) -> 111.556
Nagy számok összehasonlítása
Ez is fontos. Emlékszel, hogy az equals() metódust használjuk az objektumok összehasonlítására Java-ban. A megvalósítást vagy maga a nyelv biztosítja (a szabványos Java osztályokhoz), vagy a programozó írja felül. A BigDecimal objektumok esetében azonban nem javasolt az equals() metódus használata az összehasonlításhoz. Ennek az az oka, hogy a BigDecimal.equals() metódus csak akkor ad vissza igazat, ha a 2 szám értéke és skálája azonos: Hasonlítsuk össze az equals() metódus viselkedését a Double és BigDecimal osztályoknál:import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
Double a = 1.5;
Double b = 1.50;
System.out.println(a.equals(b));
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.equals(y));
}
}
Konzol kimenet:
true
false
Mint látható, a BigDecimal esetében az 1,5 és 1,50 számok egyenlőtlennek bizonyultak! Ez éppen az equals() metódus BigDecimal osztályban való megvalósításának sajátosságai miatt volt így . A két BigDecimal objektum pontosabb összehasonlításához jobb az összehasonlítás() metódus használata:
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal x = new BigDecimal("1.5");
BigDecimal y = new BigDecimal("1.50");
System.out.println(x.compareTo(y));
}
}
Konzol kimenet:
0
Az összehasonlítás() metódus 0-t adott vissza, ami azt jelenti, hogy 1,5 és 1,50 egyenlő. És ez az eredmény, amit vártunk! :) Ezzel a mai leckénk is véget ért. Itt az ideje, hogy visszatérjünk a feladatokhoz! :)