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.