Bitoví operátori Java

1. Prehľad

Na prácu s údajmi a premennými sa používajú operátory v jazyku Java.

V tomto tutoriále preskúmame bitových operátorov a ich prácu v prostredí Java.

2. Bitoví operátori

Bitové operátory pracujú na binárnych čísliciach alebo na bitoch vstupných hodnôt. Môžeme ich použiť na celočíselné typy - long, int, short, char, a bajt.

Pred preskúmaním rôznych bitových operátorov si najskôr uvedomme, ako fungujú.

Bitové operátory pracujú na binárnom ekvivalente desatinných čísel a vykonávajú s nimi operácie po bitoch podľa daného operátora:

  • Najskôr sa operandy prevedú na svoje binárne zastúpenie
  • Ďalej sa operátor aplikuje na každé binárne číslo a vypočíta sa výsledok
  • Nakoniec sa výsledok prevedie späť na jeho desatinné zastúpenie

Poďme to pochopiť na príklade; zoberme si dve celé čísla:

int hodnota1 = 6; int hodnota2 = 5;

Ďalej použijeme bitový operátor OR na tieto čísla:

int výsledok = 6 | 5;

Ak chcete vykonať túto operáciu, najskôr sa vypočíta binárne zastúpenie týchto čísel:

Binárne číslo hodnoty1 = 0110 Binárne číslo hodnoty2 = 0101

Potom sa operácia použije na každý bit. Výsledok vráti nové binárne číslo:

0110 0101 ----- 0111

Nakoniec výsledok 0111 sa prevedie späť na desatinné miesto, ktoré sa rovná 7:

výsledok: 7

Bitové operátory sa ďalej klasifikujú ako bitové logické operátory a operátory bitového posunu. Poďme si teraz prejsť každý typ.

3. Bitové logické operátory

Bitové logické operátory sú AND (&), OR (|), XOR (^) a NOT (~).

3.1. Po bitkách ALEBO (|)

Operátor OR porovná každú binárnu číslicu dvoch celých čísel a vráti 1, ak je ktorákoľvek z nich 1.

Je to podobné ako s logický operátor používaný s booleovcami. Výsledkom je porovnanie dvoch boolov pravda ak niektorý z nich je pravda. Podobne je výstup 1, keď je jeden z nich 1.

Príklad tohto operátora sme videli v predchádzajúcej časti:

@Test public void givenTwoIntegers_whenOrOperator_thenNewDecimalNumber () hodnota2; assertEquals (7, výsledok); 

Pozrime sa na binárne znázornenie tejto operácie:

0110 0101 ----- 0111

Tu vidíme, že použitie OR, 0 a 0 bude mať za následok 0, zatiaľ čo akákoľvek kombinácia s aspoň 1 bude mať za následok 1.

3.2. Po bitkách A (&)

Operátor AND porovnáva každú binárnu číslicu dvoch celých čísel a vracia 1, ak sú obidve 1, inak vráti 0.

Je to podobné ako u operátora && s boolovský hodnoty. Keď sú hodnoty dvoch booleanspravda výsledkom operácie && je pravda.

Použime rovnaký príklad ako je uvedené vyššie, s výnimkou toho, že namiesto | použijeme operátor & operátor:

@Test public void givenTwoIntegers_whenAndOperator_thenNewDecimalNumber () {int hodnota1 = 6; int hodnota2 = 5; int výsledok = hodnota1 & hodnota2; assertEquals (4, výsledok); }

Pozrime sa tiež na binárne znázornenie tejto operácie:

0110 0101 ----- 0100

0100 je 4 v desatinnej čiarke je preto výsledok:

výsledok: 4

3.3. Bitový XOR (^)

Operátor XOR porovnáva každú binárnu číslicu dvoch celých čísel a vracia 1, ak sú obidve porovnávané bity odlišné. To znamená, že ak bity oboch celých čísel sú 1 alebo 0, výsledok bude 0; v opačnom prípade bude výsledok 1:

@Test public void givenTwoIntegers_whenXorOperator_thenNewDecimalNumber () {int hodnota1 = 6; int hodnota2 = 5; int výsledok = hodnota1 ^ hodnota2; assertEquals (3, výsledok); }

A binárne zastúpenie:

0110 0101 ----- 0011

0011 je 3 desatinné miesto, takže výsledok je:

výsledok: 3

3.4. Bitový DOPLNOK (~)

Operátor Bitwise Not alebo Complement jednoducho znamená negáciu každého bitu vstupnej hodnoty. Trvá iba jedno celé číslo a je ekvivalentné s! operátor.

Tento operátor zmení každú binárnu číslicu celého čísla, čo znamená, že všetky 0 sa stanú 1 a všetky 1 sa stanú 0. The! operátor pracuje podobne pre boolovský hodnoty: obráti sa boolovský hodnoty z pravda do nepravdivé a naopak.

Teraz si na príklade rozumieme, ako nájsť doplnok desatinného čísla.

Urobme doplnok value1 = 6:

@Test public void givenOneInteger_whenNotOperator_thenNewDecimalNumber () {int hodnota1 = 6; int výsledok = ~ hodnota1; assertEquals (-7, výsledok); }

Hodnota v binárnom formáte je:

hodnota1 = 0000 0110

Použitím operátora komplementu bude výsledok:

0000 0110 -> 1111 1001

Toto je doplnok desatinného čísla 6. A keďže prvý (vľavo) bit je binárne 1, znamená to, že znamienko je záporné pre číslo, ktoré je uložené.

Teraz, keď sú čísla uložené ako doplnok 2, musíme najskôr nájsť doplnok 2 a potom konvertovať výsledné binárne číslo na desatinné číslo:

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

Nakoniec, 0000 0111 má 7 v desatinnej čiarke. Pretože znakový bit bol 1, ako je uvedené vyššie, výsledná odpoveď je:

výsledok: -7

3.5. Bitová operátorská tabuľka

Poďme si zhrnúť výsledok operátorov, ktorých sme doteraz videli, do porovnávacej tabuľky:

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. Operátori bitového radenia

Operátory binárneho posunu posunú všetky bity vstupnej hodnoty doľava alebo doprava na základe operátora posunu.

Pozrime sa na syntax týchto operátorov:

hodnotu 

Ľavá strana výrazu je celé číslo, ktoré je posunuté, a pravá strana výrazu označuje počet opakovaní, ktoré je potrebné posunúť.

Operátory bitového posunu sa ďalej klasifikujú ako bitové operátory ľavého a pravého bitového posunu.

4.1. Podpísaný ľavý posun [<<]

Operátor ľavého posunu posúva bity doľava o počet časov určených pravou stranou operandu. Po ľavom posune je prázdne miesto vpravo vyplnené číslom 0.

Ďalším dôležitým bodom, ktorý je potrebné poznamenať, je, že posunutie čísla o jednu sa rovná vynásobeniu číslom 2 alebo všeobecne posunutie čísla doľava o n pozície sa rovná násobeniu 2 ^n.

Zoberme hodnotu 12 ako vstupnú hodnotu.

Teraz ho posunieme o 2 miesta doľava (12 << 2) a uvidíme, aký bude konečný výsledok.

Binárny ekvivalent 12 je 00001100. Po posunutí doľava o 2 miesta je výsledkom 00110000, čo je ekvivalent 48 v desatinnej čiarke:

@Test public void givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int hodnota = 12; int leftShift = hodnota << 2; assertEquals (48, leftShift); } 

Toto funguje podobne pre zápornú hodnotu:

@Test public void givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int hodnota = -12; int leftShift = hodnota << 2; assertEquals (-48, leftShift); }

4.2. Podpísaný pravý posun [>>]

Operátor pravého radenia posúva všetky bity doprava. Prázdne miesto na ľavej strane je vyplnené v závislosti od vstupného čísla:

  • Ak je vstupné číslo záporné, pričom bit úplne vľavo je 1, potom sa prázdne miesta vyplnia číslom 1
  • Ak je vstupné číslo kladné, pričom bit vľavo je 0, potom sa prázdne miesta vyplnia číslom 0

Pokračujme v príklade s použitím 12 ako vstupu.

Teraz to posunieme o 2 miesta doprava (12 >> 2) a uvidíme, aký bude konečný výsledok.

Zadané číslo je kladné, takže po posunutí doprava o 2 miesta bude výsledok 0011, čo sú 3 desatinné miesta:

@Test public void givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int hodnota = 12; int rightShift = hodnota >> 2; assertEquals (3, rightShift); }

Pre zápornú hodnotu tiež:

@Test public void givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int hodnota = -12; int rightShift = hodnota >> 2; assertEquals (-3, pravý posun); }

4.3. Nepodpísaný pravý posun [>>>]

Tento operátor je veľmi podobný podpísanému pravému posunu. Jediný rozdiel je v tom, že prázdne miesta vľavo sú vyplnené 0 bez ohľadu na to, či je číslo kladné alebo záporné. Výsledkom bude preto vždy kladné celé číslo.

Poďme doprava posunúť rovnakú hodnotu 12:

@Test public void givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int hodnota = 12; int unsignedRightShift = hodnota >>> 2; assertEquals (3, unsignedRightShift); }

A teraz záporná hodnota:

@Test public void givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int hodnota = -12; int unsignedRightShift = hodnota >>> 2; assertEquals (1073741821, unsignedRightShift); }

5. Rozdiel medzi bitovými a logickými operátormi

Existuje niekoľko rozdielov medzi bitovými operátormi, o ktorých sme tu hovorili, a všeobecne známymi logickými operátormi.

Najprv, logické operátory pracujú ďalej boolovský výrazy a vrátiť sa boolovský hodnoty (buď pravda alebo nepravda), keďže bitové operátory pracujú na binárnych číslach celočíselných hodnôt (long, int, short, char, a bajt) a vráti celé číslo.

Logické operátory tiež vždy vyhodnotia prvý boolovský výraz a podľa jeho výsledku a použitého operátora môže alebo nemusí vyhodnotiť druhý. Na druhej strane, bitové operátory vždy vyhodnotia obidva operandy.

Nakoniec sa pri rozhodovaní na základe viacerých podmienok používajú logické operátory, zatiaľ čo bitové operátory pracujú na bitoch a vykonávajú bitové operácie.

6. Používajte puzdrá

Niektoré potenciálne prípady použitia bitových operátorov sú:

  • Komunikačné komíny, kde jednotlivé bity v hlavičke pripojenej k údajom znamenajú dôležité informácie
  • Vo vstavaných systémoch nastaviť / vyčistiť / prepnúť iba jeden bit konkrétneho registra bez úpravy zvyšných bitov
  • Na šifrovanie údajov kvôli bezpečnostným problémom pomocou operátora XOR
  • Pri kompresii údajov prevodom údajov z jednej reprezentácie na druhú, aby sa znížilo množstvo použitého priestoru

7. Záver

V tomto tutoriáli sme sa dozvedeli o typoch bitových operátorov a o tom, ako sa líšia od logických operátorov. Videli sme pre nich aj niekoľko potenciálnych prípadov použitia.

Všetky príklady kódov v tomto článku sú k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found