Tipuri de date întregi

Tipurile de date întregi sunt  byte, short, int, long și char. Conceptual, datele care aparțin tipurilor byte, short, int și long sunt numere întregi, în timp ce tipul char conține caractere (litere, cifre, semne de punctuație etc).

Întrucât caracterele se codifică în memoria calculatorului prin numere întregi fără semn, în limbajul Java asupra lor se pot aplica toate operațiile pentru numere întregi. Totusi, datorită particularităților pe care le prezintă, noi  vom trata tipul char separat.
 

Mulțimile de valori ale tipurilor întregi

Tipurile de date întregi propriu-zise sunt date în tabela de mai jos.
 
Tipul Lungimea Intervalul de valori
byte 1 octet (8 biți) [-128,  127]
short 2 octeți (16 biți) [-32768,  32767]
int 4 octeți (32 biți) [-2147483648,  2147683647]
long 8 octeți (64 biți) [-9223372036854775808,  9223372036854775807]

Se observă, deci, că deosebirea dintre diferitele tipuri de date întregi constă în lungimea reprezentării lor interne, care condiționează și mulțimea de valori a tipului respectiv. Este evident că mulțimea de valori a fiecăruia din aceste tipuri este numai o submulțime a mulțimii numerelor întregi.
 
Reprezentarea internă a datelor de tip byte, short, int si long se face sub forma de numere întregi cu semn, în sistemul de numerație binar. Primul bit al reprezentării interne este interpretat drept semn (0 pentru + si 1 pentru -). Numerele întregi pozitive se reprezintă, deci, prin numere binare care încep cu cifra 0. Numerele întregi negative se reprezintă prin complementul la doi al modulului lor.

Avand în vedere că cu n cifre în baza 2 se pot reprezenta 2n valori, se obțin domeniile de valori indicate în tabelul de mai sus. De exemplu, pentru tipul byte există 28=256 valori.

Limitele domeniilor de valori pentru fiecare tip întreg se pot exprima în binar în funcție de numărul de biți astfel:
   - tipul byte:  -27 ... 27-1;
   - tipul short: -215 ... 215-1;
   - tipul int:     -231 ... 231-1;
   - tipul long:   -264 ... 264-1.
 
Sa luăm ca exemplu numerele de tip byte, care se reprezintă intern pe o lungime de 8 biți. 

Cel mai mic numar pozitiv este, în acest caz, 00000000 (deci 0 extins pe toți cei 8 biți), iar cel mai mare numar pozitiv este01111111, care este în sistemul zecimal 27-1, adica 127.

Pentru reprezentarea numerelor negative se foloșeste complementul la 2, care se obtine astfel: se ia modulul numărului respectiv (în binar) și se inverseaza toti biții (din 0 în 1 și invers), după care se adună 1 la valoarea astfel obținută. De exemplu, numarul -108 se va reprezenta astfel: se ia modulul acestuia, 108, care se reprezinta în binar pe 8 biți sub forma 01101100. Înversând biții se obtine 10010011. Adunând 1 (în binar) la acest număr se obține 10010100 care este reprezentarea internă a numarului negativ -108 și are primul bit 1.

Remarcam că numarul -1 se reprezinta intern pe 8 biți prin 11111111, iar numărul -128 prin 10000000.

Literali de tip întreg

Literalii de tip întreg servesc pentru reprezentarea în program a valorilor numerice de tip întreg și pot fi clasificați astfel: Nu există in limbajul Java literali de tip byte sau short. Literalii de tip long se deosebesc de cei de tip int prin faptul ca se termină prin litera L sau l. Se prefera litera majuscula L, deoarece litera mică l se poate confunda cu cifra 1.

În sistemul zecimal, literalii întregi sunt șiruri de cifre zecimale care pot fi precedate de semn și nu conțin în interiorul lor separatori, cum sunt punctul, virgula sau apostroful (care se folosesc de noi în scrierea uzuală a numerelor) și nu incep cu cifra 0.
 
Exemple corecte de literali întregi în sistemul zecimal:
  - de tip int:  0   -5    276315    -176426
  - de tip long:  0L   -5L   3567286542987L

Exemple de literali întregi scriși greșit:
  27.653.816 (conține puncte);    5,187 (conține virgula); 
  3'876'293 (conține apostrofuri);
    069354       -084931 (încep cu cifra 0).

În sistemul octal, literalii întregi sunt numere cu sau fără semn, scrise în sistemul de numerație octal (cu baza opt) și care încep cu cifra 0. Amintim că cifrele sistemului octal sunt 0, 1, 2, 3, 4, 5, 6, 7.
 
Exemple de literali corecți în sistemul octal:  016724    -04507

În sistemul hexazecimal, literalii întregi sunt numere cu sau fără semn, scrise în sistemul de numerație hexazecimal (cu baza 16) și care încep cu prefixul 0x. Amintim că cifrele sistemului hexazecimal sunt: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. În locul majusculelor se pot folosi și minusculele corespunzătoare.
 
Exemple de literali corecți în sistemul hexazecimal:  0x37B2E   -0x2ab7f3
Sistemele octal și hexazecimal prezintă avantajul că au ca baze puteri ale lui 2. Din această cauză, conversia din aceste sisteme de numerație în binar pentru numerele pozitive se face simplu: fiecare cifra octală se reprezintă în binar prin trei biți, iar fiecare cifră fexazecimală prin patru biți. 
 
De exemplu, numărul octal 15132 (corespunzător literalului 015132) se va reprezenta în binar prin 001101001011010, iar numărul hexazecimal 6ac3 (corespunzator literalului 0x6ac3) se convertește în binar prin 0110101011000011.
La conversia inversă, din binar în octal, se grupează cifrele numarului binar câte trei de la dreapta la stânga, după care se înlocuiește fiecare grup de trei biți prin valoarea corespunzătoare în octal. În mod corespunzător, la conversia din binar în hexazecimal, se grupează biții câte patru de la dreapta la stânga și se înlocuiește fiecare grup prin cifra hexazecimală corespunzătoare. De exemplu, numărul binar 0110110010110011 corespunde numerelor 066263 în octal  și 6cb3 in hexazecimal.

Operații și operatori pentru date de tip întreg

Asupra datelor de tip întreg se pot aplica operații de atribuire,  de conversie de tip, operații aritmetice, de comparație,  operații de deplasare binară, operații logice pe biți și operații de atribuire compusă. Primele trei au fost discutate anterior și vom indica aici numai unele particularități ale aplicării lor în cazul datelor de tipuri întregi.

Conversia de tip și atribuirea

Diferitele tipuri de date întregi diferă între ele prin lungimea reprezentării lor interne. La convertirea unui tip mai scurt în unul mai lung (de exemplu a unui byte sau short în int) valoarea numărului rămâne neschimbată. Din această cauză, această conversie se poate face implicit. În schimb, la conversia de la o lungime mai mare la una mai mică, se rețin numai octeții situați în partea dreaptă a numărului, eliminându-se octeții din stânga care depășesc noua lungime. Prin aceasta este posibil să se modifice valoarea numărului și chiar semnul lui. Din această cauză, la efectuarea unor astfel de conversii, programatorul trebuie să-și asume raăspunderea folosind operatorul cast.
 
Exemplu
Să considerăm urmatoarea aplicație din fișierul CastInt.java.
 
/* Verificarea actiunii operatorului (cast) in cazul numerelor intregi
*/

class CastInt {
  public static void main(String args[]) {
    /* Declararea si initializarea variabilelor */
    byte b1=73, b2=-107, b3, b4, b5;
    int i1=91, i2=-103, i3=22195, i4, i5;
    /* Atribuiri cu conversie implicita de la byte la int
    */
    i4=b1; 
    i5=b2; 
    /* Atribuiri care necesita conversie explicita de la int la byte
    */
    b3=(byte)i1;
    b4=(byte)i2;
    b5=(byte)i3;
    /* Afisarea rezultatelor */
    System.out.println("i4="+i4+" i5="+i5+"\nb3="+b3+" b4="+b4+
      " b5="+b5);
  }
}

Compilând și rulând pe calculator această aplicație obținem următorul rezultat afișat pe ecran:
i4=73 i5=-107
b3=91 b4=-103 b5=-77
Analizând aceste rezultate, constatăm că:
   - valorile variabilelor i3 și i4 au fost atribuite corect, deoarece conversia s-a făcut de la lungimea de un octet la cea de 4 octeți, astfel că nu s-au alterat valorile;
   - valorile variabilelor b3 și b4 au fost atribuite corect, deși conversia s-a făcut prin (cast) de la lungimea de 4 octeți la cea de 1 octet. Explicația este că valorile atribuite se încadrau în intervalul de valori permise pentru tipul byte;
   - în cazul variabilei b5 s-a atribuit valoarea -77, deși în instrucțiunea b5=(byte)i3 variabila i3 are valoarea 22195. Prin conversie s-au modificat deci atât valoarea, cât și semnul, deoarece 22195 nu se încadrează în mulțimea de valori a tipului byte.
 
Pentru cei interesați, putem urmări cum s-au facut efectiv aceste conversii, luând în considerație reprezentările interne.

a/ Atribuirea i4=b1 unde b1 are valoarea 73.
   b1 se reprezinta intern prin octetul 01001001. Când se face conversia de la byte la int se extinde aceasta reprezentare externa prin adaugarea la stânga a trei octeți nuli. Se obține astfel numărul de tip int  00000000000000000000000001001001 care este valoarea 73 pe 4 octeți.

b/ Atribuirea i5=b2 unde b2 are valoarea negativă -107.
   b2 se reprezintă intern prin octetul 10010101 (folosind codul complementar pentru numere negative). Intrucât primul bit este 1, când se face conversia de la byte la int se adaugă la stânga trei octeți completați în întregime cu cifra 1, obținându-se reprezentarea internă 11111111111111111111111110010101. În acest fel s-a conservat semnul, obținându-se tot numărul -107, dar reprezentat pe 4 octeți.

c/ Atribuirea b3=(byte)i1 unde i1 are valoarea 91. Reprezentarea internă a lui i1 este 00000000000000000000000001011011 și se extinde pe 4 octeți. Prin conversia de la int la byte se elimină cei trei octeți din stânga, obținându-se reprezentarea pe un octet 01011011. Întrucât s-au eliminat numai zerouri din stânga, valoarea a rămas neschimbată.

d/ Atribuirea b4=(byte)i2 unde i2 are valoarea negativă -103. Reprezentarea internă a lui i2 este 11111111111111111111111110011001 fiind complementul lui 103 extins pe 4 octeți. Prin conversie la tipul byte se elimină cei trei octeți din stânga, obținându-se 10011001 care este tot numărul -103, dar reprezentat pe un singur octet.

e/ Atribuirea b5=(byte)i3, unde i3 are valoarea 22195. Reprezentarea internă a lui i3 pe patru octeti este 00000000000000000101011010110011. Prin conversie la tipul byte se elimina cei trei octeți din stânga, reținându-se octetul 10110011 care se atribuie ca valoare a lui b5. Deoarece începe cu bitul 1, aceasta se interpreteaza ca valoarea negativă -77. Constatăm astfel că prin conversie s-au modificat atât valoarea, cât și semnul. Aceasta s-a întâmplat întrucât valoarea de la care a pornit conversia nu se încadra în mulțimea de valori a tipului byte, iar la eliminarea celor trei octeți din partea stangă s-au pierdut cifre semnificative.

Operații aritmetice cu numere întregi

Asupra datelor de tip întreg se pot aplica toți operatorii aritmetici prezentați anterior. Vom prezenta aici numai unele particularități ale operațiilor aritmetice cu numere întregi și vom da exemple.
 
Tipul rezultatului operațiilor aritmetice cu numere întregi se stabileste astfel:
    a/ în cazul operațiilor de incrementare (++) și decrementare (--) tipul rezultatului este același cu tipul operandului;
    b/ pentru toate celelalte operații, dacă cel puțin unul din operanzi este de tip long, atunci rezultatul este de tip long; altfel, rezultatul este de tip int.

Remarcăm, deci, că singurele operații aritmetice care pot da rezultat de tip byte sau short sunt cele de incrementare sau decrementare.

Împarțirea întreagă

O consecință a modului de stabilire a rezultatului operațiilor aritmetice  este că, atunci când se face o operație de împărțire (/) între două numere întregi, rezultatul este un numar întreg (de tip int sau long, după caz). La împărțire se calculează, deci, numai partea întreagă a câtului.

Excepția de împărțire la zero

Este posibil ca, în operatia de împarțire întreagă, al doilea operand (împărțitorul) să fie egal cu zero. În acest caz, mașina virtuală Java generează o excepție de împărțire la zero, care face parte din clasa ArithmeticException. În programul de mai jos, din fișierul ImpartireZero.java, se testează o astfel de situație.
 
/* Testarea exceptiei de impartire la zero */

class ImpartireZero {
  public static void main(String args[]) {
    int a=5, b=0, c=0;
    System.out.println(a/b);
  }
}

Se observă că în expresia a/b opeandul b are valoarea zero. La executarea acestui program se afișeaza pe ecran următorul mesaj:
 
Exception in thread "main" java.lang.ArithmeticException: / by zero at ImpartireZero.main(ImpartireZero.java:6)

Acest mesaj se interpretează astfel: s-a produs o excepție din clasa ArithmeticException în firul de execuție "main"; excepția constă în împărțire (/) la zero și a apărut în metoda main a clasei ImpartireZero, fiind localizată în fișierul sursă ImpartireZero.java linia 6. Se poate constata cu ușurință că, într-adevar, operația care a produs excepția se găsește în locul indicat.

Înlocuind în acest fișier operația a/b prin c/b (astfel încât ambii operanzi sunt nuli) caonstatăm că, dacă repetăm compilarea și execuția, obținem aceeași excepție. Așa dar, la depistarea excepției de împărțire la zero, mașina virtuală Java testează numai împărțitorul, nu și deîmpărțitul.

Depășirea binară

La efectuarea unor operații cu numere întregi este posibil ca rezultatul să fie un numar binar mai lung decât spațiul alocat în memorie pentru tipul de date respectiv. De exemplu, dacă se înmulțesc două numere de tip int (reprezentate pe 32 biți fiecare), rezultatul poate fi un numar mai lung de 32 biți, deci a cărui valoare nu se mai încadrează în mulțimea de date a tipului int. O astfel de situație se numește depășire binară. În limbajul Java, apariția depășirii binare nu este considerată o excepție, ci calculul continuă, dar se rețin numai octeții din dreapta ai rezultatului, atâți cât corespund reprezentării interne a tipului de date respectiv (4 octeți pentru int și 8 octeți pentru long). În consecința se pierd octeții cei mai semnificativi și are loc, deci, modificarea valorii și chiar a semnului rezultatului, la fel ca în cazul conversiei de la un tip cu lungime mai mare la unul cu lungime mai mică.

Exemplu
În următoarea aplicație din fișierul Intregi.java se fac unele teste privind operațiile cu numere întregi.
 
class Intregi {
  public static void main(String args[]) {
    byte b1=73, b2=-109, b3, b4, b5;
    short s1=9000, s2=-11000, s3;
    int i1=900000, i2=-1100000, i3, i4, i5;
    long m1=10000000000L, m2=-200000000000L, m3, m4;
    b3=(byte)(-b2);
    b4=(byte)(b1+b2);
    b5=++b1;
    s3=(short)(s2/s1);
    s4=(short)(s2%s1); // restul impartirii s2/s1
    i3=i1+i2;
    i4=i1*i2;
    i5=(int)(m2/i1);
    m3=m2-m1;
    m4=m2*m1;
    System.out.println("b3="+b3+" b4="+b4+" b5="+b5);
    System.out.println("s3="+s3+" s4="+s4);
    System.out.println("i3="+i3+" i4="+i4+" i5="+i5);
    System.out.println("m3="+m3+" m4="+m4);
    System.out.println("b5*b2="+(b5*b2)+ "s1*s2="+(s1*s2));
  }
}

Remarcăm că la calcularea valorilor variabilelor b3, b4 și s3 a fost necesar să se folosească conversia explicită (cast), deoarece valorile expresiilor din paranteze din partea dreaptă a operandului de atribuire sunt de tip int, în timp ce variabilele din partea stânga sunt de tip byte sau short. În mod similar s-a folosit castul la calcularea lui i5, deoarece expresia m2/m1 este de tipul long. Se poate constata cu usurință, suprimând din program operatorii cast din expresiile respective, că dacă nu se folosesc acești operatori sunt semnalate erori de compilare. În schimb, nu a fost necesar să se recurgă la cast la calcularea valorii lui b5, deoarece expresia ++b este de tip byte.

Executând acest program, se obțin pe ecran următoarele rezultate:
 
b3=109 b4=-36 b5=74
s3=-1 s4=-2000
i3=-200000 i4=2137445376 i5=-222222
m3=-210000000000 m4=-7751640039368425472
b5*b2=-8066 s1*s2=-99000000

Din aceste rezultate constatăm că:

  - s-a obținut s3=-1 si nu s3=-1.222222... deoarece în expresia s2/s1 ambii operanzi sunt de tipuri întregi, deci rezultatul este întreg (împărțire întreagă). Din același motiv s-a obținut i5=-222222 si nu -222222.222222....;
  - la calcularea lui i4 nu s-a obținut valoarea corectă -990000000000, ci valoarea 2137445376. Cauza este că valoarea depășește marginea superioară a valorilor de tip int, deci s-a produs o depășire binară și s-au trunchiat octeții cei mai semnificativi. Tot o depășire binară s-a produs și la calcularea lui m4 (de data aceasta pentru tipul long);
 - valorile produselor b5*b2 și s1*s2 au fost calculate și afisate corect, deși ele depășesc limitele mulțimilor de valori de tip byte, respectiv de tip short. Aceasta s-a produs deoarece expresiile respective sunt de tip int.

Comparația

Operatorii de comparație pot fi aplicați pentru orice fel de operanzi numerici. Ca exemplu, în fișierul ComparInt.java se da un program, în care se compară diferite numere întregi și se afișează rezultatele.
 
/* Testarea operatorilor de comparatie in cazul tipurilor
 de date intregi
*/

class ComparInt {
  public static void main(String args[]) {
    byte b1=48, b2=-17;
    short s1=2765, s2=-12970;
    int i1=762983, i2=48, i3=-12970;
    long m1=876432906528L, m2=48;
    System.out.println(b1==b2);
    System.out.println(b1==i2);
    System.out.println(s1!=i2);
    System.out.println(i2!=m2);
    System.out.println(m2>i2);
    System.out.println(m2>=i2);
    System.out.println(s2<i3);
    System.out.println(i3<=s2);
  }
}

Executând acest program se obțin pe ecran următoarele rezultate sub forma de valori booleene:
 
false
true
true
false
false
true
false
true

Având în vedere că true înseamnă adevărat, iar false înseamnă  fals, se poate constata cu ușurinta că aceste rezultate sunt corecte. Remarcăm, de asemenea, că rezultatul comparației depinde numai de valorile numerelor comparate, nu și de tipul acestora.
 

Operații de deplasare binară

Urmând "tradiția" limbajului C, limbajul Java conține și operatori de deplasare binară. Aceștia sunt operatori binari (cu doi operanzi) fără efect lateral. Tipul rezultatului operației se stabilește la fel ca în cazul operațiilor aritmetice cu numere întregi. Valoarea rezultată se stabilește astfel: se ia reprezentarea internă a primului operand și se deplasează la stânga sau la dreapta cu un numar de poziții binare egal cu cel de al doilea operand.

Operatorii de deplasare și efectele lor sunt prezentate în tabela de mai jos, în care a și s sunt operanzi care aparțin unor tipuri întregi.
 
Operator Expresie Efect
<<
a<<s
deplasare la stânga cu s poziții binare
>>
a>>s
deplasare la dreapta cu s poziții binare, cu conservarea semnului
>>>
a>>>s
deplasare la dreapta fără semn, cu s poziții binare

Deplasarea la stânga cu s poziții este echivalenta cu înmulțirea numărului cu 2s. Dacă s este suficient de mare, poate avea loc o depășire binară, la fel ca în cazul înmulțirii aritmetice (cu operatorul *).

Deplasarea la dreapta cu s poziții cu operatorul >> este echivalenta cu împărțirea întreagă la 2s.

Deplasarea biților la dreapta cu s pozitii cu operatorul >>> are asupra numerelor pozitive același efect ca cel al operatorului >>. În schimb, în cazul operanzilor negativi, în cazul operatorului >>> nu se mai conservă semnul, iar modulul numărului se modifică. Aceasta se întâmplă, întrucât pe pozițiile eliberate din partea stângă se înserează bitul 0.

Exemplu
În fișierul Deplasari.java se dă un exemplu de aplicație, în care se testează acțiunea operatorilor de deplasare binară.
 
/* Testarea operatiilor de deplasare binara */

class Deplasari {
  public static void main(String args[]) {
    byte b1=15, b2;
    int i1=1024, i2=-1024;
    b2=(byte)(b1<<3);
    System.out.println("b1="+b1+" b2="+b2);
    System.out.println("i1<<4="+(i1<<4)+" i1>>4="+(i1>>4)+
      " i1>>>4="+(i1>>>4));
    System.out.println("i2<<4="+(i2<<4)+" i2>>4="+(i2>>4)+
      " i2>>>4="+(i2>>>4));
  }
}

Rezultatele afișate la executarea acestui program sunt următoarele:
 
b1=15 b2=120
i1<<4=16384 i1>>4=64 i1>>>4=64
i2<<4=-16384 i2>>4=-64 i2>>>4=268435392

Având în vedere că 23=8 și 24=16, rezultatele obținute pot fi verificate cu ușurință. Constatăm ca singura deosebire dintre efectele operatorilor >> și >>> apare când primul operand este negativ.
 
Operatorul >>> nu există în limbajul C, el fiind introdus numai în Java.

Pentru a ințelege mai bine efectul operatorilor de deplasare, să urmărim ce se întâmplă în exemplul de mai sus la nivelul reprezentării interne a datelor (în binar).

Având în vedere că 1024=210, reprezentările interne ale operanzilor i1 și i2 sunt următoarele:
   i1=00000000000000000000010000000000
   i2=11111111111111111111110000000000
După aplicarea operatorului << (deplasare binară la stânga cu inserare de zerouri pe spațiile libere din dreapta) obținem:
  - pentru operația i1<<4:   00000000000000000100000000000000
  - pentru operația i2<<4:   11111111111111111100000000000000
ceeace reprezintă în zecimal numerele 214=16384 si, respectiv, -214=-16384.

După aplicarea operatorului >> (deplasare la dreapta cu conservarea semnului) se obține:
  - pentru operația i1>>4:   00000000000000000000000001000000
  - pentru operația i2>>4:   11111111111111111111111111000000
ceeace reprezintă în sistemul zecimal numerele 26=64 și, respectiv, -26=-64. Remarcăm că în cazul operandului negativ i2, la deplasarea la dreapta s-a înserat pe pozițiile libere bitul 1 pentru a se conserva semnul.

După aplicarea operatorului >>> (deplasare la dreapta fără conservarea semnului) se obține:
  - pentru operația i1>>>4:  00000000000000000000000001000000
  - pentru operația i2>>>4:  00001111111111111111111111000000
Pentru operandul pozitiv i1 s-a obținut un rezultat identic cu cel precedent. În schimb, în cazul operandului negativ i2, pe pozițiile eliberate din partea stângă s-a înserat bitul 0, ceeace a dus la schimbarea semnului și a valorii rezultatului față de cazul deplăsarii cu conservarea semnului.

Operații logice pe biți

 Tot urmând "tradiția" limbajelor C/C++, în limbajul Java se pot utiliza pentru tipurile de date întregi și operatorii logici pe biți ~, &, | si ^. Aceștia sunt operatori fără efect lateral. Operațiile logice se fac la nivel de bit, adică între fiecare bit al operandului din stânga și bitul corespunzător al operandului din dreapta, considerându-se ca 0 este echivalent cu false, iar 1 este echivalent cu true

Operatorul unar ~ exprimă negația logică, deci înlocuirea lui 0 cu 1 și invers.
Operatorii binari &, | si ^ acționează la fel ca în cazul tipului boolean, numai că se aplică la nivel de bit.

Acțiunea operatorilor este dată în tabela de mai jos, în care a și b sunt cei doi operanzi, iar ai si bisunt biții de pe pozitia i a acestor operanzi. În tabelă se dă efectul fiecărei operații asupra bitului i al rezultatului.
 
ai
bi
~a
a&b
a|b
a^b
0
0
1
0
0
0
0
1
1
0
1
1
1
0
0
0
1
1
1
1
0
1
1
0

Exemplu
În fișierul LogicaBiti.java este dat un exemplu de program, în care se testează operațiile logice pe biți. Pentru a se verifica manual mai ușor, am considerat că oprațiile se fac asupra datelor de tip byte. Este bine să avem însă in vedere că rezultatele operațiilor sunt de tip int. Aceasta se poate constata cu usurința dacă încercăm să eliminăm castul din instrucțiunea în care se calculează b3.
 
/* Testarea operatiilor logice pe biti */

class LogicaBiti {
  public static void main(String args[]) {
    byte b1=17, b2=-95, b3;
    b3=(byte)(b1&b2); // este necesara conversie de la int la byte
    System.out.println("~b1="+(~b1)+" b1&b2="+b3+" b1|b2="+(b1|b2)+
      " b1^b2="+(b1^b2));
  }
}

Rezultatele afișate la executarea acestui program sunt următoarele:
 
~b1=-18 b1&b2=1 b1|b2=-79 b1^b2=-80
Iată și cum decurg operațiile din exemplul de mai sus la nivel de bit:

     b1: 00010001 echivalent cu  17
     b2: 10100001 echivalent cu -95
    ~b1: 11101110 echivalent cu -18
  b1&b2: 00000001 echivalent cu   1
  b1|b2: 10110001 echivalent cu -79
  b1^b2: 10110000 echibalent cu -80
Bineînțeles că toate aceste rezultate ar trebui exprimate pe 32 biți, prin prelungire la stânga cu cate 18 cifre de 0 sau de 1 după caz, astfel încât să se conserve semnul.

Aplicarea operatorilor de atribuire compusă

Pentru operanzii de tipuri întregi se pot aplica toți operatorii de atribuire compusă +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>=.
 
Exemplu
În programul din fișierul AtribComp.java se testează unele operații de atribuire compusă. Iată acest program:
 
/* Testarea operatorilor de atribuire compusa */

class AtribComp {
  public static void main(String args[]) {
    int m=176, b=-15, c=16, d=-28;
    System.out.println(m+" "+(m+=b)+" "+m);
    System.out.println((m/=d)+" "+m);
    System.out.println(b+" "+(b<<=2)+" "+b);
    System.out.println(c+" "+(c|=b)+" "+c);
  }
}

La executarea programului se obțin pe ecran următoarele rezultate:
 
176 161 161
-5 -5
-15 -60 -60
16 -44 -44

Prima linie afișată conține: 
  - valoarea variabilei m înainte de evaluarea expresiei m+=b;
  - valoarea expresiei m+=b; ea este egală cu m+b adică cu 176-15;
  - valoarea variabilei m după calcularea acestei expresii.
Recomandăm sa explicați în mod similar și celelalte linii afișate.



© Copyright 2000 - Severin BUMBARU, Universitatea "Dunărea de Jos" din Galați