Java bitni operateri

1. Pregled

Operatori se koriste u jeziku Java za rad s podacima i varijablama.

U ovom uputstvu istražit ćemo Bitwise Operators i kako oni rade u Javi.

2. Bitovni operateri

Bitovni operatori rade na binarnim znamenkama ili bitovima ulaznih vrijednosti. Možemo ih primijeniti na cjelobrojne vrste - dugo, int, kratko, char, i bajt.

Prije istraživanja različitih bitnih operatora, prvo shvatimo kako oni rade.

Bitni operatori rade na binarnom ekvivalentu decimalnih brojeva i izvode operacije nad njima bit po bit prema zadanom operatoru:

  • Prvo se operandi pretvaraju u njihov binarni prikaz
  • Zatim se operator primjenjuje na svaki binarni broj i izračunava se rezultat
  • Konačno, rezultat se pretvara natrag u njegov decimalni prikaz

Razumijemo na primjeru; uzmimo dvije cijeli brojevi:

int vrijednost1 = 6; int vrijednost2 = 5;

Dalje, primijenimo bitni ILI operator na ove brojeve:

rezultat int = 6 | 5;

Da bi se izvela ova operacija, prvo će se izračunati binarni prikaz ovih brojeva:

Binarni broj vrijednosti1 = 0110 Binarni broj vrijednosti2 = 0101

Tada će se operacija primijeniti na svaki bit. Rezultat vraća novi binarni broj:

0110 0101 ----- 0111

Konačno, rezultat 0111 pretvorit će se natrag u decimalu koja je jednaka 7:

rezultat: 7

Bitni operatori dalje se klasificiraju kao bitni logički i bitni operateri pomaka. Prođimo sada svaku vrstu.

3. Bitni logički operatori

Lopovski logički operatori su AND (&), OR (|), XOR (^) i NOT (~).

3.1. Bitno ILI (|)

Operator OR uspoređuje svaku binarnu znamenku dviju cijelih brojeva i daje 1 ako je bilo koja od njih 1.

Ovo je slično || logički operator koji se koristi s logičkim vrijednostima. Kada se usporede dvije logičke vrijednosti rezultat je pravi ako je ijedan od njih pravi. Slično tome, izlaz je 1 kada je bilo koji od njih 1.

Primjer ovog operatora vidjeli smo u prethodnom odjeljku:

@Test javna praznina givenTwoIntegers_whenOrOperator_thenNewDecimalNumber () value2; assertEquals (7, rezultat); 

Pogledajmo binarni prikaz ove operacije:

0110 0101 ----- 0111

Ovdje možemo vidjeti da će upotreba OR, 0 i 0 rezultirati 0, dok će bilo koja kombinacija s najmanje 1 rezultirati 1.

3.2. Bitno I (&)

Operator AND uspoređuje svaku binarnu znamenku dviju cijelih brojeva i daje 1 ako su obje 1, inače vraća 0.

Ovo je slično operateru && sa boolean vrijednosti. Kad vrijednosti dvije booleovi jesu pravi rezultat operacije && je pravi.

Upotrijebimo isti primjer kao gore, osim što sada koristimo operator & umjesto | operater:

@Test javna praznina givenTwoIntegers_whenAndOperator_thenNewDecimalNumber () {int value1 = 6; int vrijednost2 = 5; int rezultat = vrijednost1 & vrijednost2; assertEquals (4, rezultat); }

Pogledajmo i binarni prikaz ove operacije:

0110 0101 ----- 0100

0100 je 4 u decimalu, dakle, rezultat je:

rezultat: 4

3.3. Bitno XOR (^)

XOR operator uspoređuje svaku binarnu znamenku dviju cijelih brojeva i daje 1 ako su oba uspoređena bita različita. To znači da će, ako su bitovi oba cijela broja 1 ili 0, rezultat biti 0; u suprotnom, rezultat će biti 1:

@Test javna praznina givenTwoIntegers_whenXorOperator_thenNewDecimalNumber () {int value1 = 6; int vrijednost2 = 5; int rezultat = vrijednost1 ^ vrijednost2; assertEquals (3, rezultat); }

I binarni prikaz:

0110 0101 ----- 0011

0011 je 3 u decimalnom značenju, dakle, rezultat je:

rezultat: 3

3.4. DOPUNSKI DOPUNI (~)

Operator Bitwise Not ili Complement jednostavno znači negaciju svakog bita ulazne vrijednosti. Potreban je samo jedan cijeli broj i ekvivalentan je! operater.

Ovaj operator mijenja svaku binarnu znamenku cijelog broja, što znači da svih 0 postaje 1, a svih 1 postaje 0. The! operater radi slično za boolean vrijednosti: obrće se boolean vrijednosti iz pravi do lažno i obrnuto.

Sada shvatimo na primjeru kako pronaći komplement decimalnog broja.

Napravimo dopunu vrijednosti1 = 6:

@Test javna praznina givenOneInteger_whenNotOperator_thenNewDecimalNumber () {int value1 = 6; int rezultat = ~ vrijednost1; assertEquals (-7, rezultat); }

Vrijednost u binarnom obliku je:

vrijednost1 = 0000 0110

Primjenom operatora komplementa rezultat će biti:

0000 0110 -> 1111 1001

Ovo je nadopuna decimalnog broja 6. A budući da je prvi (krajnji lijevi) bit 1 u binarnom obliku, to znači da je znak negativan za broj koji je pohranjen.

Sada, budući da su brojevi pohranjeni kao komplement dvojke, prvo moramo pronaći komplement njegove dvojke, a zatim pretvoriti dobiveni binarni broj u decimalni broj:

1111 1001 -> 0000 0110 + 1 -> 0000 0111

Napokon, 0000 0111 je 7 u decimalu. Budući da je znakovni bit bio 1, kao što je gore spomenuto, stoga je odgovor:

rezultat: -7

3.5. Tablica operatora u bitovima

Sažmimo rezultat operatora koje smo do sada vidjeli u usporednoj tablici:

A B A | B A&B A ^ B ~ A 0 0 0 0 0 1 1 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0

4. Operatori pomicanja u bitovima

Binarni operateri pomaka pomiču sve bitove ulazne vrijednosti ulijevo ili udesno na temelju operatora pomaka.

Pogledajmo sintaksu ovih operatora:

vrijednost 

Lijeva strana izraza je cijeli broj koji je pomaknut, a desna strana izraza označava koliko je puta potrebno pomaknuti.

Operatori pomaka u bitima dalje su klasificirani kao bitni operateri pomaka ulijevo i u bitima.

4.1. Potpisan lijevi pomak [<<]

Lijevi operator pomicanja pomiče bitove ulijevo za broj puta određenih desnom stranom operanda. Nakon smjene ulijevo, prazan prostor u desnoj popunjava se s 0.

Još jedna važna stvar koju treba napomenuti je da pomicanje broja za jedan ekvivalentno je množenju s 2 ili, općenito, lijevo pomicanje broja za n položaja ekvivalentno je množenju s 2 ^n.

Uzmimo vrijednost 12 kao ulaznu vrijednost.

Sada ćemo ga pomaknuti za 2 mjesta ulijevo (12 << 2) i vidjeti kakav će biti konačni rezultat.

Binarni ekvivalent 12 je 00001100. Nakon pomicanja ulijevo za 2 mjesta, rezultat je 00110000, što je ekvivalentno 48 u decimalu:

@Test javna praznina givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int vrijednost = 12; int leftShift = vrijednost << 2; assertEquals (48, leftShift); } 

Ovo djeluje slično za negativnu vrijednost:

@Test javna praznina givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int vrijednost = -12; int leftShift = vrijednost << 2; assertEquals (-48, leftShift); }

4.2. Potpisan desni pomak [>>]

Operator desnog pomaka pomiče sve bitove udesno. Prazno mjesto na lijevoj strani popunjava se ovisno o ulaznom broju:

  • Kada je ulazni broj negativan, gdje je krajnji lijevi bit 1, tada će se prazna mjesta popuniti s 1
  • Kad je ulazni broj pozitivan, gdje je krajnji lijevi bit 0, prazna mjesta popunit će se s 0

Nastavimo primjer koristeći 12 kao ulaz.

Sada ćemo ga pomaknuti za 2 mjesta udesno (12 >> 2) i vidjeti kakav će biti konačni rezultat.

Ulazni broj je pozitivan, pa je nakon pomicanja udesno za 2 mjesta rezultat 0011, što je 3 u decimalu:

@Test javna praznina givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int value = 12; int rightShift = vrijednost >> 2; assertEquals (3, rightShift); }

Također, za negativnu vrijednost:

@Test javna praznina givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int value = -12; int rightShift = vrijednost >> 2; assertEquals (-3, rightShift); }

4.3. Nepotpisani desni pomak [>>>]

Ovaj je operator vrlo sličan potpisanom operateru desne smjene. Jedina je razlika u tome što se prazna mjesta s lijeve strane popunjavaju s 0 bez obzira na to je li broj pozitivan ili negativan. Stoga će rezultat uvijek biti pozitivan cijeli broj.

Pomaknimo udesno istu vrijednost 12:

@Test javna praznina givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int value = 12; int unsignedRightShift = vrijednost >>> 2; assertEquals (3, unsignedRightShift); }

A sada, negativna vrijednost:

@Test javna praznina givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int value = -12; int unsignedRightShift = vrijednost >>> 2; assertEquals (1073741821, unsignedRightShift); }

5. Razlika između bitnih i logičkih operatora

Postoji nekoliko razlika između bitnih operatora o kojima smo ovdje govorili i poznatijih logičkih operatora.

Prvi, logički operatori rade na boolean izrazi i vratiti boolean vrijednosti (bilo pravi ili lažno), dok bitni operatori rade na binarnim znamenkama cjelobrojnih vrijednosti (dugo, int, kratko, char, i bajt) i vratite cijeli broj.

Također, logički operatori uvijek procjenjuju prvi boolean i, ovisno o njegovom rezultatu i korištenom operatoru, može ili ne mora procijeniti drugi. S druge strane, bitni operatori uvijek procjenjuju oba operanda.

Napokon, logički operatori koriste se u donošenju odluka na temelju više uvjeta, dok bitni operatori rade na bitovima i izvode bit po bit operacije.

6. Koristite slučajeve

Neki potencijalni slučajevi upotrebe bitnih operatora su:

  • Komunikacijski snopovi gdje pojedinačni bitovi u zaglavlju priloženom podacima označavaju važne informacije
  • U ugrađenim sustavima za postavljanje / brisanje / prebacivanje samo jednog bita određenog registra bez modificiranja preostalih bitova
  • Za šifriranje podataka zbog sigurnosnih problema pomoću XOR operatora
  • U kompresiji podataka pretvaranjem podataka iz jedne reprezentacije u drugu, kako bi se smanjila količina korištenog prostora

7. Zaključak

U ovom smo tutorijalu naučili o vrstama bitnih operatora i kako se oni razlikuju od logičkih operatora. Također smo vidjeli nekoliko potencijalnih slučajeva upotrebe za njih.

Svi primjeri koda u ovom članku dostupni su na GitHubu.