CodeGym /Blog Java /Aleatoriu /Operatori Java pe biți
John Squirrels
Nivel
San Francisco

Operatori Java pe biți

Publicat în grup
În lecția de astăzi, ne vom familiariza cu operatorii Java pe biți și vom lua în considerare exemple despre cum să lucrăm cu aceștia. Probabil că ești familiarizat cu cuvântul „bit”. Dacă nu, să ne amintim ce înseamnă :) Un bit este cea mai mică unitate de informație dintr-un computer. Numele său provine din cifra binară . Un bit poate fi exprimat prin unul dintre cele două numere: 1 sau 0. Există un sistem special de numere binar bazat pe unu și zero. Nu ne vom adânci într-o junglă matematică aici. Vom observa doar că orice număr din Java poate fi convertit în formă binară. Pentru a face acest lucru, trebuie să utilizați clasele wrapper.
Operatori pe biți - 1
De exemplu, iată cum puteți face acest lucru pentru un int :

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
Ieșirea consolei: 101010110 1010 10110 (am adăugat spațiu pentru a fi mai ușor de citit) este numărul 342 în sistemul zecimal. De fapt, am împărțit acest număr în biți individuali: zerouri și unu. Operațiile efectuate pe biți se numesc pe biți .
  • ~ - pe biți NU.
Acest operator este foarte simplu: trece peste fiecare bit al numărului nostru și inversează bitul: zerourile devin unu, iar unii devin zerouri. Dacă îl aplicăm numărului nostru 342, iată ce se întâmplă: 101010110 este 342 reprezentat ca un număr binar 010101001 este valoarea expresiei ~342 Să încercăm să punem asta în practică:

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(~x);
   }
}
Ieșirea consolei: 169 169 este rezultatul nostru ( 010101001 ) în sistemul familiar, zecimal :)
  • & - pe biți și
După cum puteți vedea, arată destul de asemănător cu AND logic ( && ). Operatorul && , vă veți aminti, returnează adevărat numai dacă ambii operanzi sunt adevărati. Bit cu bit și funcționează într-un mod similar: compară două numere bit cu bit. Comparația produce un al treilea număr. De exemplu, să luăm numerele 277 și 432: 110110000 este 277 reprezentat ca un număr binar 1000101011 este 432 reprezentat ca un număr binar Apoi, operatorul & compară primul bit al numărului superior cu primul bit al numărului de jos. Deoarece acesta este un operator AND, rezultatul va fi 1 numai dacă ambii biți sunt 1. În orice alt caz, rezultatul este 0. 100010101 &Operatorul & Mai întâi, comparăm primii biți ai celor două numere, apoi al doilea biți, apoi al treilea și așa mai departe. După cum puteți vedea, în doar două cazuri sunt ambii biți corespunzători în numerele egale cu 1 (primul și al cincilea biți). Toate celelalte comparații au produs 0s. Deci, în final, am primit numărul 10001000. În sistemul zecimal, acesta corespunde cu numărul 272. Să verificăm:

public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
Ieșire consolă: 272
  • | - SAU pe biți.
Acest operator funcționează în același mod: comparând două numere bit cu bit. Abia acum dacă cel puțin unul dintre biți este 1, atunci rezultatul este 1. Să ne uităm la aceleași numere (277 și 432): 100010101 | 110110000 _______________ 110110101 - rezultat al | operator Iată un rezultat diferit: singurii biți care rămân zero sunt acei biți care au fost zero în ambele numere. Rezultatul este numărul 110110101. În sistemul zecimal, acesta corespunde numărului 437 Să verificăm:

public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
Ieșire consolă: 437 Am calculat totul corect! :)
  • ^ - XOR pe biți (SAU exclusiv)
Nu am întâlnit încă acest operator. Dar nu este nimic complicat în asta. Este similar cu operatorul OR obișnuit. Există o diferență: OR obișnuit returnează adevărat dacă cel puțin un operand este adevărat. Dar nu trebuie să fie unul singur: dacă ambii operanzi sunt adevărati, rezultatul este adevărat. Dar OR exclusiv returnează adevărat numai dacă exact unul dintre operanzi este adevărat. Dacă ambii operanzi sunt adevărati, OR obișnuit returnează adevărat ("cel puțin unul adevărat"), dar XOR returnează fals. De aceea se numește SAU exclusiv. Știind cum funcționează operatorii anteriori pe biți, probabil că puteți calcula cu ușurință 277 ^ 432. Dar să mai cercetăm împreună o dată :) 100010101 ^ 110110000 _______________ 010100101 - rezultatul ^operator Acesta este rezultatul nostru. Acei biți care erau aceiași în ambele numere produc un 0 (adică testul „singurul” a eșuat). Dar biții care formau o pereche 0-1 sau 1-0 au devenit unii. Rezultatul nostru este numărul 010100101. În sistemul zecimal, acesta corespunde numărului 165. Să vedem dacă calculele noastre sunt corecte:

public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
Ieșire consolă: 165 Super! Totul este așa cum ne-am gândit :) Acum este timpul să facem cunoștință cu operatorii de biți. Numele vorbește de la sine. Luăm un număr și îi mutăm biții la stânga sau la dreapta :) Să vedem cum arată:

Schimbați la stânga

O deplasare a biților la stânga este indicată de << Iată un exemplu:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
În acest exemplu, numărul x = 64 se numește valoare. Sunt părțile din valoare pe care le vom schimba. Vom muta biții la stânga (ai fi putut ghici acest lucru după direcția operatorului << ) În sistemul binar, numărul 64 = 1000000 Numărul y = 3 se numește distanță de deplasare. Distanța de deplasare indică câți biți la dreapta/stânga doriți să mutați biții numărului x În exemplul nostru, îi vom deplasa cu 3 biți la stânga. Pentru a vedea mai clar procesul de schimbare, priviți imaginea. În acest exemplu, folosim int s. Ints ocupă 32 de biți în memoria computerului. Așa arată numărul nostru original 64:
Operatori pe biți - 2
Și acum luăm fiecare dintre părțile noastre și le deplasăm literalmente la stânga cu 3 locuri:
Operatori pe biți - 3
Uită-te la ce avem. După cum puteți vedea, toți biții noștri s-au deplasat și alte 3 zerouri au fost adăugate de la marginea intervalului. Trei, pentru că ne-am deplasat cu 3. Dacă am fi deplasat cu 10, s-ar fi adăugat 10 zerouri. Astfel, expresia x << y înseamnă „deplasarea biților numărului x la stânga cu y locuri”. Rezultatul expresiei noastre este numărul 1000000000, care este 512 în sistemul zecimal. Sa verificam:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Ieșire consolă: 512 Spot on! Teoretic, biții ar putea fi mutați la nesfârșit, dar pentru că numărul nostru este un int , avem doar 32 de cifre binare disponibile. Dintre acestea, 7 sunt deja ocupate de 64 (1000000). Prin urmare, dacă am muta 27 de locuri la stânga, singurul nostru s-ar deplasa dincolo de intervalul tipului de date și s-ar pierde. Ar rămâne doar zerouri!

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 26;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Ieșire consolă: 0 După cum era de așteptat, cel a trecut dincolo de cei 32 de biți disponibili și a dispărut. Am încheiat cu un număr de 32 de biți format din zerouri.
Operatori pe biți - 4
Desigur, aceasta corespunde cu 0 în sistemul zecimal. Iată o regulă simplă pentru reținerea deplasărilor la stânga: Pentru fiecare deplasare la stânga, numărul este înmulțit cu 2. Să încercăm să calculăm următoarea expresie fără imagini ale biților 111111111 << 3 Trebuie să înmulțim numărul 111111111 cu 2 . Ca rezultat, obținem 888888888. Să scriem ceva cod și să verificăm:

public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
Ieșire consolă: 888888888

Schimbați la dreapta

Această operație se notează cu >> . Face același lucru, dar în cealaltă direcție! :) Nu vom reinventa roata. Să încercăm cu același int 64.

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 2;// Shift distance

       int z = (x >> y);
       System.out.println(z);
   }
}
Operatori pe biți - 5
Operatori pe biți - 6
Ca urmare a unei deplasări la dreapta cu 2, cele două zerouri extreme din numărul nostru se deplasează în afara intervalului și se pierd. Obținem 10000, care corespunde cu numărul 16 din sistemul zecimal Ieșirea consolei: 16 Iată o regulă simplă pentru a reține deplasările la dreapta: Fiecare schimbare la dreapta se împarte la doi, eliminând orice rest. De exemplu, 35 >> 2 înseamnă că trebuie să împărțim 35 la 2 de două ori, eliminând resturile 35/2 = 17 (renunțați restul 1) 17/2 = 8 (renunțați restul 1) În cele din urmă, 35 >> 2 ar trebui să să fie egal cu 8. Să verificăm:

public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
Ieșire consolă: 8

Precedența operatorului în Java

În timp ce scrieți și citiți cod, veți găsi adesea expresii care combină mai multe operații. Este foarte important să înțelegeți ordinea în care vor fi executate (în caz contrar, s-ar putea să fiți surprins de rezultat) Deoarece Java are o mulțime de operațiuni, fiecare dintre ele a primit un loc într-un tabel special:

Precedența operatorului

Operatori Precedenta
postfix expr++ expr--
unar ++expr --expr +expr ~ !
Multiplicativ * / %
aditiv + -
schimb << >> >>>
relaționale < > <= >= instanceof
egalitate == !=
ȘI pe biți &
SAU exclusiv pe biți ^
SAU inclusiv pe biți |
ȘI logic &&
SAU logic ||
ternar ? :
misiune = += -= *= /= %= &= ^= |= <<= >>= >>>=
Toate operațiunile sunt efectuate de la stânga la dreapta, ținând cont de precedența lor. De exemplu, dacă scriem

int x  = 6 - 4/2;
atunci se va executa mai întâi operația de împărțire ( 4/2 ). Deși vine pe locul al doilea, are o prioritate mai mare. Parantezele și parantezele indică prioritate maximă. Probabil îți amintești asta de la școală. De exemplu, dacă le adăugați la expresie

int x  = (6 - 4)/2;
atunci scăderea se efectuează mai întâi, deoarece este cuprinsă între paranteze. Precedența operatorului logic && este destul de scăzută (vezi tabelul), așa că de obicei va fi ultimul. De exemplu:

boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
Această expresie va fi executată după cum urmează:
  • 4/2 = 2

boolean x = 6 - 2 > 3 && 12*12 <= 119;
  • 12*12 = 144

boolean x = 6 - 2 > 3 && 144 <= 119;
  • 6-2 = 4

boolean x = 4 > 3 && 144 <= 119;
În continuare, se execută operatorii de comparație:
  • 4 > 3 = adevărat

boolean x = true && 144 <= 119;
  • 144 <= 119 = fals

boolean x = true && false;
Și, în sfârșit, operatorul AND ( && ) va fi executat ultimul.

boolean x = true && false;
boolean x = false;
De exemplu, operatorul addition( + ) are o prioritate mai mare decât operatorul de comparare != (nu este egal); Prin urmare, în expresia

boolean x = 7 != 6+1;
se va efectua mai întâi operația 6+1, apoi verificarea 7 != 7 (care se evaluează ca fals) și, în final, atribuirea rezultatului (fals) variabilei x (alocarea are în general cea mai mică prioritate dintre toți operatorii ; vezi masa). Pf! A fost o lecție uriașă, dar ai reușit-o! Dacă nu ați înțeles pe deplin unele dintre aceste lecții sau anterioare, nu vă faceți griji. Vom atinge aceste subiecte de mai multe ori în viitor. Câteva lecții CodeGym despre operații logice și numerice. Nu vom ajunge la acestea prea curând, dar nu este rău să le citiți acum.
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION