Java bitvise operatører

1. Oversigt

Operatører bruges på Java-sproget til at betjene data og variabler.

I denne vejledning undersøger vi Bitwise-operatører, og hvordan de fungerer i Java.

2. Bitvise operatører

Bitvis operatører arbejder på binære cifre eller bits af inputværdier. Vi kan anvende disse på heltalstyperne - lang, int, kort, char, og byte.

Før vi udforsker de forskellige bitvise operatører, skal vi først forstå, hvordan de fungerer.

Bitvis operatører arbejder på et binært ækvivalent med decimaltal og udfører operationer på dem bit for bit ifølge den givne operator:

  • For det første konverteres operanderne til deres binære repræsentation
  • Dernæst anvendes operatøren på hvert binært tal, og resultatet beregnes
  • Endelig konverteres resultatet tilbage til dets decimale repræsentation

Lad os forstå med et eksempel; lad os tage to heltal:

int-værdi1 = 6; int-værdi2 = 5;

Lad os derefter anvende en bitvis ELLER operator på disse tal:

int resultat = 6 | 5;

For at udføre denne operation beregnes først den binære repræsentation af disse tal:

Binært antal værdi1 = 0110 Binært antal værdi2 = 0101

Derefter anvendes operationen på hver bit. Resultatet returnerer et nyt binært tal:

0110 0101 ----- 0111

Endelig resultatet 0111 konverteres tilbage til decimal, som er lig med 7:

resultat: 7

Bitvise operatorer klassificeres yderligere som bitvise logiske og bitvise skiftoperatører. Lad os nu gennemgå hver type.

3. Bitvise logiske operatører

De bitvise logiske operatorer er AND (&), OR (|), XOR (^) og NOT (~).

3.1. Bitvis ELLER (|)

OR-operatøren sammenligner hvert binært ciffer med to heltal og giver 1 tilbage, hvis en af ​​dem er 1.

Dette svarer til || logisk operator brugt med booleanske. Når to booleaner sammenlignes, er resultatet rigtigt hvis en af ​​dem er rigtigt. Tilsvarende er output 1, når en af ​​dem er 1.

Vi så et eksempel på denne operatør i det foregående afsnit:

@ Test offentlig ugyldighed givenTwoIntegers_whenOrOperator_thenNewDecimalNumber () værdi2; assertEquals (7, resultat); 

Lad os se den binære repræsentation af denne operation:

0110 0101 ----- 0111

Her kan vi se, at brug af OR, 0 og 0 vil resultere i 0, mens enhver kombination med mindst en 1 vil resultere i 1.

3.2. Bitvis OG (&)

AND-operatoren sammenligner hvert binært tal med to heltal og giver 1 tilbage, hvis begge er 1, ellers returnerer den 0.

Dette svarer til && operatøren med boolsk værdier. Når værdierne på to booleanere er rigtigt resultatet af en && operation er rigtigt.

Lad os bruge det samme eksempel som ovenfor, undtagen nu at bruge & operatoren i stedet for | operatør:

@Test offentlig ugyldighed givenTwoIntegers_whenAndOperator_thenNewDecimalNumber () {int værdi1 = 6; int-værdi2 = 5; int resultat = værdi1 & værdi2; assertEquals (4, resultat); }

Lad os også se den binære repræsentation af denne operation:

0110 0101 ----- 0100

0100 er 4 i decimal er resultatet derfor:

resultat: 4

3.3. Bitvis XOR (^)

XOR-operatoren sammenligner hvert binært ciffer med to heltal og giver 1 tilbage, hvis begge de sammenlignede bits er forskellige. Dette betyder, at hvis bits af begge heltal er 1 eller 0, bliver resultatet 0; Ellers bliver resultatet 1:

@Test offentlig ugyldighed givenTwoIntegers_whenXorOperator_thenNewDecimalNumber () {int værdi1 = 6; int-værdi2 = 5; int-resultat = værdi1 ^ værdi2; assertEquals (3, resultat); }

Og den binære repræsentation:

0110 0101 ----- 0011

0011 er 3 i decimal, derfor er resultatet:

resultat: 3

3.4. Bitvis KOMPLEMENT (~)

Bitwise Not eller Complement-operatør betyder simpelthen negation af hver bit af inputværdien. Det tager kun et heltal, og det svarer til! operatør.

Denne operatør ændrer hvert binært tal i heltal, hvilket betyder at alle 0 bliver 1 og alle 1 bliver 0. Den! operatøren arbejder på samme måde for boolsk værdier: det vender boolsk værdier fra rigtigt til falsk og omvendt.

Lad os nu forstå med et eksempel, hvordan man finder komplementet af et decimaltal.

Lad os gøre komplementet af værdi1 = 6:

@Test offentligt ugyldigt givenOneInteger_whenNotOperator_thenNewDecimalNumber () {int værdi1 = 6; int resultat = ~ værdi1; assertEquals (-7, resultat); }

Værdien i binær er:

værdi1 = 0000 0110

Ved at anvende komplementoperatøren bliver resultatet:

0000 0110 -> 1111 1001

Dette er ens komplement af decimaltallet 6. Og da den første (længst til venstre) bit er 1 i binær, betyder det, at tegnet er negativt for det nummer, der er lagret.

Nu, da tallene er gemt som 2-komplement, skal vi først finde dets 2-komplement og derefter konvertere det resulterende binære tal til et decimaltal:

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

Endelig er 0000 0111 7 i decimal. Da tegnbiten var 1 som nævnt ovenfor, er det resulterende svar derfor:

resultat: -7

3.5. Bitvis operatørbord

Lad os sammenfatte resultatet af de operatører, vi hidtil har set i en sammenligningstabel:

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. Bitvise skiftoperatører

Binære skiftoperatører skifter alle bitene i inputværdien enten til venstre eller højre baseret på skiftoperatøren.

Lad os se syntaksen for disse operatører:

værdi 

Venstre side af udtrykket er det heltal, der forskydes, og højre side af udtrykket angiver antallet af gange, det skal skiftes.

Bitvise skiftoperatører klassificeres yderligere som bitvise venstre skifteoperatorer.

4.1. Venstre skift underskrevet [<<]

Venstre skiftoperatøren skifter bitene til venstre med det antal gange, der er angivet af operandens højre side. Efter venstre skift udfyldes det tomme rum til højre med 0.

Et andet vigtigt punkt at bemærke er, at forskydning af et tal med et svarer til at multiplicere det med 2 eller generelt til venstre forskydning af et tal med n positioner svarer til multiplikation med 2 ^n.

Lad os tage værdien 12 som inputværdien.

Nu vil vi flytte det to steder til venstre (12 << 2) og se, hvad der bliver det endelige resultat.

Den binære ækvivalent af 12 er 00001100. Efter at have skiftet til venstre med to steder, er resultatet 00110000, hvilket svarer til 48 i decimal:

@Test offentlig ugyldighed givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int værdi = 12; int leftShift = værdi << 2; assertEquals (48, leftShift); } 

Dette fungerer på samme måde for en negativ værdi:

@Test offentlig ugyldighed givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int værdi = -12; int leftShift = værdi << 2; assertEquals (-48, leftShift); }

4.2. Signeret højre skift [>>]

Den højre skiftoperatør skifter alle bits til højre. Det tomme rum i venstre side udfyldes afhængigt af inputnummeret:

  • Når et inputnummer er negativt, hvor biten til venstre er 1, udfyldes de tomme mellemrum med 1
  • Når et inputnummer er positivt, hvor den venstre bit er 0, så udfyldes de tomme mellemrum med 0

Lad os fortsætte eksemplet ved hjælp af 12 som input.

Nu vil vi flytte det to steder til højre (12 >> 2) og se, hvad der bliver det endelige resultat.

Inputnummeret er positivt, så efter at have skiftet til højre med 2 steder, er resultatet 0011, hvilket er 3 i decimal:

@Test offentlig ugyldighed givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int værdi = 12; int rightShift = værdi >> 2; assertEquals (3, rightShift); }

Også for en negativ værdi:

@Test offentlig ugyldighed givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int værdi = -12; int rightShift = værdi >> 2; assertEquals (-3, rightShift); }

4.3. Usigneret højre skift [>>>]

Denne operatør ligner meget den signerede højre skiftoperatør. Den eneste forskel er, at de tomme mellemrum til venstre er fyldt med 0, uanset om antallet er positivt eller negativt. Derfor vil resultatet altid være et positivt heltal.

Lad os højre skifte den samme værdi på 12:

@Test offentlig ugyldighed givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int værdi = 12; int unsignedRightShift = værdi >>> 2; assertEquals (3, unsignedRightShift); }

Og nu, den negative værdi:

@Test offentlig ugyldighed givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int værdi = -12; int unsignedRightShift = værdi >>> 2; assertEquals (1073741821, unsignedRightShift); }

5. Forskel mellem bitvise og logiske operatører

Der er et par forskelle mellem de bitvise operatorer, vi har diskuteret her, og de mere almindeligt kendte logiske operatorer.

Først, logiske operatører arbejder på boolsk udtryk og vende tilbage boolsk værdier (enten rigtigt eller falsk), der henviser til bitvis operatører arbejder på binære cifre af heltalværdier (lang, int, kort, char, og byte) og returnerer et heltal.

Også, logiske operatører evaluerer altid den første boolsk udtryk og afhængigt af dets resultat og den anvendte operatør evaluerer det måske det andet. På den anden side, bitvis operatører evaluerer altid begge operander.

Endelig bruges logiske operatorer til at træffe beslutninger baseret på flere betingelser, mens bitvise operatorer arbejder på bits og udfører bit for bit-operationer.

6. Brug sager

Nogle potentielle anvendelsestilfælde for bitvise operatører er:

  • Kommunikationsstakke, hvor de enkelte bits i overskriften, der er knyttet til dataene, betyder vigtig information
  • I indlejrede systemer kan du indstille / rydde / skifte kun en enkelt bit af et specifikt register uden at ændre de resterende bits
  • At kryptere data af sikkerhedsmæssige årsager ved hjælp af XOR-operatøren
  • I datakomprimering ved at konvertere data fra en repræsentation til en anden for at reducere mængden af ​​brugt plads

7. Konklusion

I denne vejledning lærte vi om typerne af bitvise operatører, og hvordan de adskiller sig fra logiske operatører. Vi så også nogle potentielle brugssager for dem.

Alle kodeeksemplerne i denne artikel er tilgængelige på GitHub.


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