Java Bitwise-operatører

1. Oversikt

Operatører brukes på Java-språket for å operere på data og variabler.

I denne opplæringen vil vi utforske Bitwise-operatører og hvordan de fungerer i Java.

2. Bitvise operatører

Bitvis operatører jobber med binære sifre eller biter av inngangsverdier. Vi kan bruke disse på heltallstyper - lang, int, kort, røye, og byte.

Før vi utforsker de forskjellige bitvise operatørene, må vi først forstå hvordan de fungerer.

Bitvis operatører arbeider med et binært ekvivalent av desimaltall og utfører operasjoner på dem bit for bit i henhold til den gitte operatøren:

  • Først konverteres operandene til deres binære representasjon
  • Deretter blir operatøren brukt på hvert binære tall, og resultatet blir beregnet
  • Til slutt konverteres resultatet tilbake til desimalrepresentasjonen

La oss forstå med et eksempel; la oss ta to heltall:

int-verdi1 = 6; int-verdi2 = 5;

Deretter la oss bruke en bitvis ELLER operator på disse tallene:

int resultat = 6 | 5;

For å utføre denne operasjonen, beregnes først den binære representasjonen av disse tallene:

Binært antall verdi1 = 0110 Binært antall verdi2 = 0101

Da vil operasjonen bli brukt på hver bit. Resultatet returnerer et nytt binært tall:

0110 0101 ----- 0111

Endelig resultatet 0111 konverteres tilbake til desimal som er lik 7:

resultat: 7

Bitvise operatører blir videre klassifisert som bitvise logiske og bitvise skiftoperatører. La oss nå gå gjennom hver type.

3. Bitvise logiske operatører

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

3.1. Bitvis ELLER (|)

OR-operatøren sammenligner hvert binære siffer med to heltall og gir tilbake 1 hvis en av dem er 1.

Dette ligner på || logisk operatør brukt med booleanere. Når to booleans sammenlignes blir resultatet ekte hvis noen av dem er det ekte. Tilsvarende er utgangen 1 når en av dem er 1.

Vi så et eksempel på denne operatøren i forrige avsnitt:

@Test offentlig tomrom gittTwoIntegers_whenOrOperator_thenNewDecimalNumber () verdi2; assertEquals (7, resultat); 

La oss se den binære representasjonen av denne operasjonen:

0110 0101 ----- 0111

Her kan vi se at bruk av OR, 0 og 0 vil resultere i 0, mens enhver kombinasjon med minst en 1 vil resultere i 1.

3.2. Bitvis OG (&)

AND-operatoren sammenligner hvert binære siffer med to heltall og gir tilbake 1 hvis begge er 1, ellers returnerer den 0.

Dette ligner på && operatøren med boolsk verdier. Når verdiene til to booleanere er ekte resultatet av en && operasjon er ekte.

La oss bruke det samme eksemplet som ovenfor, bortsett fra nå å bruke & operatoren i stedet for | operatør:

@Test offentlig ugyldighet givenTwoIntegers_whenAndOperator_thenNewDecimalNumber () {int-verdi1 = 6; int-verdi2 = 5; int resultat = verdi1 & verdi2; assertEquals (4, resultat); }

La oss også se den binære representasjonen av denne operasjonen:

0110 0101 ----- 0100

0100 er 4 i desimal er resultatet derfor:

resultat: 4

3.3. Bitvis XOR (^)

XOR-operatøren sammenligner hvert binære siffer med to heltall og gir tilbake 1 hvis begge de sammenlignede bitene er forskjellige. Dette betyr at hvis biter av begge heltallene er 1 eller 0, blir resultatet 0; Ellers blir resultatet 1:

@Test offentlig ugyldighet gittTwoIntegers_whenXorOperator_thenNewDecimalNumber () {int-verdi1 = 6; int-verdi2 = 5; int resultat = verdi1 ^ verdi2; assertEquals (3, resultat); }

Og den binære representasjonen:

0110 0101 ----- 0011

0011 er 3 i desimal, derfor er resultatet:

resultat: 3

3.4. Bitvis KOMPLEMENT (~)

Bitvis not eller komplement-operatør betyr ganske enkelt negasjonen av hver bit av inngangsverdien. Det tar bare ett heltall, og det tilsvarer! operatør.

Denne operatøren endrer hvert binære siffer i heltallet, noe som betyr at alle 0 blir 1 og alle 1 blir 0.! operatøren fungerer på samme måte for boolsk verdier: det snur boolsk verdier fra ekte til falsk og vice versa.

La oss nå forstå med et eksempel hvordan vi finner komplementet til et desimaltall.

La oss gjøre komplementet av verdi1 = 6:

@Test offentlig ugyldighet gittOneInteger_whenNotOperator_thenNewDecimalNumber () {int-verdi1 = 6; int resultat = ~ verdi1; assertEquals (-7, resultat); }

Verdien i binær er:

verdi1 = 0000 0110

Ved å bruke komplementoperatøren blir resultatet:

0000 0110 -> 1111 1001

Dette er komplementet til desimaltallet 6. Og siden den første (lengst til venstre) biten er 1 i binær, betyr det at tegnet er negativt for tallet som er lagret.

Nå, siden tallene er lagret som 2-komplement, må vi først finne 2-komplementet og deretter konvertere det resulterende binære tallet til et desimaltall:

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

Endelig er 0000 0111 7 i desimal. Siden tegnbiten var 1 som nevnt ovenfor, er det resulterende svaret:

resultat: -7

3.5. Bitvis operatørbord

La oss oppsummere resultatet av operatørene vi hittil har sett i en sammenligningstabell:

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

Binære skiftoperatører forskyver alle bitene av inngangsverdien enten til venstre eller høyre basert på skiftoperatøren.

La oss se syntaksen for disse operatørene:

verdi 

Venstre side av uttrykket er heltallet som forskyves, og høyre side av uttrykket angir antall ganger det må forskyves.

Bitvise skiftoperatører er videre klassifisert som bitvise skiftoperatører.

4.1. Signert venstre skift [<<]

Venstre skiftoperatør skifter bitene til venstre med antall ganger spesifisert av høyre side av operanden. Etter venstre skift fylles det tomme rommet til høyre med 0.

Et annet viktig poeng å merke seg er at å skifte et tall med ett tilsvarer å multiplisere det med 2, eller generelt, venstre skifte et tall med n posisjoner tilsvarer multiplikasjon med 2 ^n.

La oss ta verdien 12 som inngangsverdien.

Nå vil vi flytte den to steder til venstre (12 << 2) og se hva som blir det endelige resultatet.

Den binære ekvivalenten 12 er 00001100. Etter å ha skiftet til venstre med to plasser, er resultatet 00110000, som tilsvarer 48 i desimal:

@Test offentlig ugyldig givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int-verdi = 12; int leftShift = verdi << 2; assertEquals (48, leftShift); } 

Dette fungerer på samme måte for en negativ verdi:

@Test offentlig ugyldig givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int verdi = -12; int leftShift = verdi << 2; assertEquals (-48, leftShift); }

4.2. Signert høyre skift [>>]

Høyre skiftoperatør forskyver alle biter til høyre. Det tomme rommet på venstre side fylles avhengig av inngangsnummeret:

  • Når et inngangstall er negativt, der den venstre biten er 1, blir de tomme feltene fylt med 1
  • Når et inngangstall er positivt, hvor den venstre biten er 0, vil de tomme feltene fylles med 0

La oss fortsette eksemplet med 12 som input.

Nå vil vi flytte den to steder til høyre (12 >> 2) og se hva som blir det endelige resultatet.

Inngangstallet er positivt, så etter å ha skiftet til høyre med to steder, er resultatet 0011, som er 3 i desimal:

@Test offentlig ugyldig givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int verdi = 12; int rightShift = verdi >> 2; assertEquals (3, rightShift); }

Også for en negativ verdi:

@Test offentlig ugyldighet gittOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int verdi = -12; int rightShift = verdi >> 2; assertEquals (-3, rightShift); }

4.3. Usignert høyre skift [>>>]

Denne operatøren er veldig lik den signerte høyre skiftoperatøren. Den eneste forskjellen er at de tomme plassene til venstre er fylt med 0, uavhengig av om tallet er positivt eller negativt. Derfor vil resultatet alltid være et positivt heltall.

La oss høyre skifte samme verdi på 12:

@Test offentlig ugyldighet gittOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int verdi = 12; int unsignedRightShift = verdi >>> 2; assertEquals (3, unsignedRightShift); }

Og nå, den negative verdien:

@Test offentlig ugyldighet gittOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int verdi = -12; int unsignedRightShift = verdi >>> 2; assertEquals (1073741821, unsignedRightShift); }

5. Forskjellen mellom bitvise og logiske operatører

Det er noen forskjeller mellom de bitvise operatorene vi har diskutert her, og de mer kjente logiske operatorene.

Først, logiske operatører jobber med boolsk uttrykkene og tilbake boolsk verdier (enten ekte eller falsk), mens bitvise operatører jobber med binære sifre av heltallverdier (lang, int, kort, røye, og byte) og returner et heltall.

Også, logiske operatører evaluerer alltid den første boolsk uttrykk og, avhengig av resultatet og operatøren som brukes, kan eller ikke evaluerer det andre. På den andre siden, bitvis operatører evaluerer alltid begge operandene.

Til slutt brukes logiske operatører til å ta beslutninger basert på flere forhold, mens bitvise operatører jobber på bits og utfører bit for bit-operasjoner.

6. Bruk tilfeller

Noen potensielle bruksområder for bitvise operatører er:

  • Kommunikasjonsstabler der de enkelte bitene i overskriften som er knyttet til dataene, betyr viktig informasjon
  • I innebygde systemer kan du sette / fjerne / veksle bare en enkelt bit av et bestemt register uten å endre de gjenværende bitene
  • For å kryptere data for sikkerhetsproblemer ved hjelp av XOR-operatøren
  • I datakomprimering ved å konvertere data fra en representasjon til en annen, for å redusere mengden plass som brukes

7. Konklusjon

I denne opplæringen lærte vi om typene bitvis operatører og hvordan de er forskjellige fra logiske operatører. Vi så også noen potensielle brukssaker for dem.

Alle kodeeksemplene i denne artikkelen er tilgjengelige på GitHub.


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