Viliam Búr

2. 8. 2008

Celé čísla v jazyku Java

V jazyku Java máme štyri primitívne typy určené na prácu s celými číslami: byte, short, int, a long. Sú to celočíselné typy so znamienkom, s veľkosťou 1, 2, 4, 8 bajtov, čiže 8, 16, 32, 64 bitov. (Aj typ char určený na prácu s písmenami je v podstate 16-bitové celé číslo bez znamienka, a možno s ním robiť matematické operácie, ale kvôli prehľadnosti programu to neodporúčam robiť bezdôvodne.)

Základné matematické operácie robíme znamienkami "+" sčítanie, "-" odčítanie, "*" násobenie, "/" celočíselné delenie, "%" zvyšok po celočíselnom delení.

int a = 100;
int b = 6;

System.out.println(a + b);  // 106
System.out.println(a - b);  //  94
System.out.println(a * b);  // 600
System.out.println(a / b);  //  16
System.out.println(a % b);  //   4

Znamienko "+" okrem sčítania znamená aj spojenie reťazcov, a má rovnakú prioritu ako matematické "+" a "-". Ak pri vypisovaní výsledku výpočtu pripájame aj textový popis, pozor na prioritu znamienok; radšej okolo výpočtu pridajme zátvorky.

int x = 2;
int y = 3;

System.out.println("Spolu " + x + y);    // Spolu 23
System.out.println("Spolu " + (x + y));  // Spolu 5

Čísla môžeme porovnávať pomocou operátorov "==" rovná sa, "!=" nerovná sa, "<" je menšie, ">" je väčšie, "<=" je menšie alebo rovné, ">=" je väčšie alebo rovné.

int x = 2;
int y = 3;

if (x == y) {
 System.out.println("X sa rovna Y");   
}
if (x != y) {
 System.out.println("X sa nerovna Y");   
}
if (x < y) {
 System.out.println("X je mensie ako Y");   
}
if (x > y) {
 System.out.println("X je vacsie ako Y");   
}
if (x <= y) {
 System.out.println("X je mensie alebo rovne Y");   
}
if (x >= y) {
 System.out.println("X je vacsie alebo rovne Y");   
}

Každému z týchto primitívnych typov zodpovedá objektový typ: java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long; tieto typy sú odvodené od abstraktného typu java.lang.Number. Vďaka objektovým typom môžeme celé čísla používať tam, kde sa vyžadujú objekty, napríklad pri množinách a zoznamoch. Objektové typy poskytujú aj niekoľko užitočných statických metód. Z primitívnej hodnoty vyrobíme objekt pomocou statickej metódy valueOf; z objektu vyrobíme primitívnu hodnotu pomocou metód byteValue, shortValue, intValue, longValue.

int i = 5;
Integer j = Integer.valueOf(i);
int k = j.intValue();

System.out.println(i);  // 5
System.out.println(j);  // 5
System.out.println(k);  // 5

Jazyk Java umožňuje takzvaný autoboxing, čiže automatické dopĺňanie metód na premenu primitívnej hodnoty na objektovú a naopak. Predchádzajúci príklad by sa dal napísať aj jednoduchšie, ale znamenalo by to to isté.

int i = 5;
Integer j = i;
int k = j;

System.out.println(i);  // 5
System.out.println(j);  // 5
System.out.println(k);  // 5

S autoboxingom treba zaobchádzať opatrne. Lepšie je používať metódy explicitne, môžeme sa tak vyhnúť hľadaniu veľmi nenápadných chýb. Premenná typu "Integer" môže obsahovať hodnotu null, premenná typu "int" vždy obsahuje číslo; ak na to zabudneme, môže pri premene nastať výnimka NullPointerException.

Pri používaní typov "Integer" a "int" sa líši aj význam znamienka "==". Pre primitívne typy znamienko "==" porovnáva čísla. Pre objektové typy znamienko "==" testuje, či je to ten istý objekt. Ak teda máme dva rôzne objekty, ktoré vyjadrujú rovnaké číslo, znamienko "==" vráti, že sú rôzne; rovnosť obsahu zistíme pomocou metódy "equals". Pri dvoch rôznych primitívnych typoch, napríklad "int" a "long" znamienko "==" porovná, či obsahujú rovnaké číslo; pri objektoch "Integer" a "Long" bude metóda "equals" vždy vracať negatívny výsledok. Pri práci s číslami ako objektmi treba dávať veľký pozor, čo vlastne porovnávame.

(C) 2008 Viliam Búr viliam-bur.blogspot.com

int i = 5;
int j = 5;
if (i == j) {  // ano
 System.out.println("I a J sa rovnaju");
}

Integer I = new Integer(5);
Integer J = new Integer(5);
if (I == J) {  // nie
 System.out.println("I a J su ten isty objekt");
}
if (I.equals(J)) {  // ano
 System.out.println("I a J su rovnake");
}

int x = 5;
long y = 5;
if (x == y) {  // ano
 System.out.println("X a Y sa rovnaju");
}

Number X = new Integer(5);
Number Y = new Long(5);
if (X == Y) {  // nie
 System.out.println("X a Y su ten isty objekt");
}
if (X.equals(Y)) {  // nie!
 System.out.println("X a Y su rovnake");
}
if (X.longValue() == Y.longValue()) {  // ano
 System.out.println("X a Y sa rovnaju");
}

Rozsah jednotlivých celočíselných typov si môžeme vypočítať podľa počtu ich bitov, alebo použijeme ich statické premenné "MIN_VALUE" a "MAX_VALUE".

System.out.println("Byte " + Byte.MIN_VALUE + " " + Byte.MAX_VALUE);
// Byte -128 127
System.out.println("Short " + Short.MIN_VALUE + " " + Short.MAX_VALUE);
// Short -32768 32767
System.out.println("Integer " + Integer.MIN_VALUE + " " + Integer.MAX_VALUE);
// Integer -2147483648 2147483647
System.out.println("Long " + Long.MIN_VALUE + " " + Long.MAX_VALUE);
// Long -9223372036854775808 9223372036854775807

Ak chceme číslo zapísať do reťazca, môžeme použiť metódu "toString" (existuje aj statická) alebo pomocou znamienka "+" pripojiť číslo k reťazcu (napríklad prázdnemu). Ak to chceme urobiť v inej ako desiatkovej sústave, použijeme statickú metódu "toString" s dvoma parametrami. Základ číselnej sústavy nesmie byť väčší ako "Character.MAX_RADIX", ale väčšinou potrebujeme základy od 2 do 16, a tie sú v poriadku. Pre najčastejšie základy existujú aj statické metódy "toBinaryString", "toOctalString", "toHexString" ktoré konvertujú parameter ako celé číslo bez znamienka.

int x = 123456789;
System.out.println(Integer.toHexString(x));   //  75bcd15
System.out.println(Integer.toString(x, 16));  //  75bcd15

int y = -123456789;
System.out.println(Integer.toHexString(y));   // f8a432eb
System.out.println(Integer.toString(y, 16));  // -75bcd15

Ak chceme naopak z reťazca získať číslo, použijeme statickú metódu "parseInt" ("parseByte",...) alebo "valueOf", podľa toho, či chceme dostať primitívny typ alebo objekt. (Ak reťazec obsahuje číslo bez znamienka, získané napríklad pomocou metódy "toHexString", môže nastať prekročenie rozsahu a výnimka "NumberFormatException".)

System.out.println(Integer.parseInt("cafe", 16));  // 51966

S celými číslami môžeme robiť aj bitové operácie: "&" logický súčin (obidva bity), "|" logický súčet (aspoň jeden bit), "^" exkluzívny logický súčet (práve jeden bit). Bity môžeme posúvať pomocou operátorov: "<<" posun doľava, ">>" posun doprava so zachovaním znamienka, ">>>" posun doprava s doplnením núl.

int i = Integer.parseInt("0011", 2);
int j = Integer.parseInt("0101", 2);

System.out.println(Integer.toBinaryString(i & j));  // 0001
System.out.println(Integer.toBinaryString(i | j));  // 0111
System.out.println(Integer.toBinaryString(i ^ j));  // 0110

int k = -100;

System.out.println(Integer.toBinaryString(k));
// 11111111111111111111111110011100
System.out.println(Integer.toBinaryString(k << 1));
// 11111111111111111111111100111000
System.out.println(Integer.toBinaryString(k >> 1));
// 11111111111111111111111111001110
System.out.println(Integer.toBinaryString(k >>> 1));
// 01111111111111111111111111001110

Náhodné celé čísla získame pomocou objektu java.util.Random. Tu máme simuláciu hádzania kockou:

java.util.Random r = new java.util.Random();
for (int i = 0; i < 100; i++) {
 System.out.println(1 + r.nextInt(6));
}

Súvisiace články:

Menovky:

0 komentárov:

Zverejnenie komentára

Prihlásiť na odber Zverejniť komentáre [Atom]

<< Domov