CodeGym /Java Blog /Willekeurig /Java Bitwise-operators
John Squirrels
Niveau 41
San Francisco

Java Bitwise-operators

Gepubliceerd in de groep Willekeurig
In de les van vandaag maken we kennis met Java Bitwise Operators en bekijken we voorbeelden van hoe ermee te werken. U bent waarschijnlijk bekend met het woord "bit". Zo niet, laten we ons herinneren wat het betekent :) Een bit is de kleinste informatie-eenheid in een computer. De naam komt van binaire cijfers . Een bit kan worden uitgedrukt door een van twee getallen: 1 of 0. Er is een speciaal binair getallenstelsel gebaseerd op enen en nullen. We gaan hier niet in een wiskundige jungle duiken. We merken alleen op dat elk getal in Java kan worden omgezet in binaire vorm. Om dit te doen, moet u de wrapper-klassen gebruiken.
Bitsgewijze operatoren - 1
Zo kun je dit bijvoorbeeld doen voor een int :

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
Console-uitvoer: 101010110 1010 10110 (ik heb de spatie toegevoegd om het leesbaarder te maken) is het getal 342 in het decimale systeem. We hebben dit getal eigenlijk opgesplitst in afzonderlijke bits: nullen en enen. Bewerkingen die op bits worden uitgevoerd, worden bitsgewijze genoemd .
  • ~ - bitsgewijs NIET.
Deze operator is heel eenvoudig: hij passeert elk bit van ons getal en draait het bit om: nullen worden enen en enen worden nullen. Als we het toepassen op ons getal 342, gebeurt het volgende: 101010110 is 342 weergegeven als een binair getal 010101001 is de waarde van de uitdrukking ~342 Laten we proberen dit in praktijk te brengen:

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(~x);
   }
}
Console-uitvoer: 169 169 is ons resultaat ( 010101001 ) in het bekende, decimale systeem :)
  • & - bitsgewijs EN
Zoals je kunt zien, lijkt het erg op de logische AND ( && ). U zult zich herinneren dat de operator && alleen 'true' retourneert als beide operanden waar zijn. Bitwise & werkt op een vergelijkbare manier: het vergelijkt twee getallen beetje bij beetje. De vergelijking levert een derde getal op. Laten we bijvoorbeeld de getallen 277 en 432 nemen: 110110000 is 277 weergegeven als een binair getal 1000101011 is 432 weergegeven als een binair getal Vervolgens vergelijkt de operator & het eerste bit van het bovenste getal met het eerste bit van het onderste getal. Omdat dit een AND-operator is, is het resultaat alleen 1 als beide bits 1 zijn. In elk ander geval is het resultaat 0. 100010101 && operator Eerst vergelijken we de eerste bits van de twee getallen, dan de tweede bits, dan de derde, enzovoort. Zoals u kunt zien, zijn in slechts twee gevallen beide overeenkomstige bits in de getallen gelijk aan 1 (de eerste en vijfde bits). Alle andere vergelijkingen leverden nullen op. Dus uiteindelijk kregen we het getal 10001000. In het decimale systeem komt het overeen met het getal 272. Laten we eens kijken:

public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
Console-uitgang: 272
  • | - bitsgewijs OF.
Deze operator werkt op dezelfde manier: twee getallen beetje bij beetje vergelijken. Alleen nu als tenminste één van de bits 1 is, dan is het resultaat 1. Laten we naar dezelfde getallen kijken (277 en 432): 100010101 | 110110000 _______________ 110110101 - resultaat van de | operator Hier krijgen we een ander resultaat: de enige bits die nullen blijven, zijn de bits die nullen waren in beide getallen. Het resultaat is het getal 110110101. In het decimale systeem komt het overeen met het getal 437 Laten we eens kijken:

public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
Console output: 437 We hebben alles goed berekend! :)
  • ^ - bitsgewijze XOR (exclusief OR)
We zijn deze operator nog niet tegengekomen. Maar er is niets ingewikkelds aan. Het is vergelijkbaar met de gewone OR-operator. Er is één verschil: de gewone OR geeft 'true' terug als ten minste één operand waar is. Maar het hoeft niet één te zijn: als beide operanden waar zijn, is het resultaat waar. Maar exclusieve OR retourneert alleen waar als precies één van de operanden waar is. Als beide operanden waar zijn, retourneert de gewone OR waar ("ten minste één waar"), maar XOR retourneert onwaar. Daarom wordt het exclusieve OR genoemd. Als je weet hoe de vorige bitsgewijze operatoren werken, kun je waarschijnlijk gemakkelijk 277 ^ 432 berekenen. Maar laten we er nog een keer samen op ingaan :) 100010101 ^ 110110000 _______________ 010100101 - resultaat van de ^operator Dat is ons resultaat. Die bits die in beide getallen hetzelfde waren, produceren een 0 (wat betekent dat de "enige" test is mislukt). Maar de bits die een 0-1 of 1-0 paar vormden, werden eenheden. Ons resultaat is het getal 010100101. In het decimale systeem komt het overeen met het getal 165. Laten we eens kijken of onze berekeningen kloppen:

public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
Console-uitgang: 165 Super! Alles is zoals we dachten :) Nu is het tijd om kennis te maken met bitshifters. De naam spreekt voor zich. We nemen een nummer en verplaatsen de bits naar links of rechts :) Laten we eens kijken hoe het eruit ziet:

Schakel naar links

Een verschuiving van bits naar links wordt aangegeven door << Hier is een voorbeeld:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
In dit voorbeeld wordt het getal x = 64 de waarde genoemd. Het zijn de bits van de waarde die we zullen verschuiven. We verschuiven de bits naar links (je had dit kunnen raden aan de hand van de richting van de << operator) In het binaire systeem is het getal 64 = 1000000 Het getal y = 3 wordt de verplaatsingsafstand genoemd. De verschuivingsafstand geeft aan hoeveel bits naar rechts/links u de bits van het getal x wilt verschuiven . In ons voorbeeld verschuiven we ze 3 bits naar links. Kijk naar de afbeelding om het verschuivingsproces duidelijker te zien. In dit voorbeeld gebruiken we int s. Ints nemen 32 bits in beslag in het geheugen van de computer. Zo ziet ons originele nummer 64 eruit:
Bitsgewijze operatoren - 2
En nu nemen we elk van onze bits en verschuiven ze letterlijk 3 plaatsen naar links:
Bitsgewijze operatoren - 3
Kijk eens wat we hebben. Zoals je kunt zien, zijn al onze bits verschoven en zijn er nog eens 3 nullen toegevoegd vanaf de rand van het bereik. Drie, omdat we met 3 waren verschoven. Als we met 10 waren verschoven, zouden er 10 nullen zijn toegevoegd. De uitdrukking x << y betekent dus "verplaats de bits van het getal x y plaatsen naar links". Het resultaat van onze uitdrukking is het getal 1000000000, dat is 512 in het decimale systeem. Laten we het controleren:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Console-uitgang: 512 Spot on! Theoretisch zouden de bits eindeloos kunnen worden verschoven, maar omdat ons getal een int is , hebben we slechts 32 binaire cijfers beschikbaar. Hiervan zijn er al 7 bezet door 64 (1000000). Daarom, als we 27 plaatsen naar links zouden verschuiven, zou onze enige buiten het bereik van het gegevenstype komen en verloren gaan. Alleen nullen zouden overblijven!

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 26;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Console-uitvoer: 0 Zoals verwacht, ging de ene verder dan de 32 beschikbare bits en verdween. We eindigden met een 32-bits getal dat alleen uit nullen bestond.
Bitsgewijze operatoren - 4
Dit komt natuurlijk overeen met 0 in het decimale stelsel. Hier is een eenvoudige regel voor het onthouden van verschuivingen naar links: voor elke verschuiving naar links wordt het getal vermenigvuldigd met 2. Laten we proberen de volgende uitdrukking te berekenen zonder plaatjes van bits 111111111 << 3 We moeten het getal 111111111 vermenigvuldigen met 2 . Als resultaat krijgen we 888888888. Laten we wat code schrijven en controleren:

public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
Console-uitgang: 888888888

Schakel naar rechts

Deze bewerking wordt aangeduid met >> . Het doet hetzelfde, maar dan in de andere richting! :) We gaan het wiel niet opnieuw uitvinden. Laten we het proberen met dezelfde int 64.

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 2;// Shift distance

       int z = (x >> y);
       System.out.println(z);
   }
}
Bitsgewijze operatoren - 5
Bitsgewijze operatoren - 6
Als gevolg van een verschuiving naar rechts met 2, raken de twee uiterste nullen in ons getal buiten bereik en gaan verloren. We krijgen 10000, wat overeenkomt met het getal 16 in het decimale systeem Console-uitvoer: 16 Hier is een eenvoudige regel voor het onthouden van verschuivingen naar rechts: elke verschuiving naar rechts wordt gedeeld door twee, waarbij de rest wordt verwijderd. 35 >> 2 betekent bijvoorbeeld dat we 35 twee keer moeten delen door 2, waarbij we de rest weggooien 35/2 = 17 (gooi rest 1 weg) 17/2 = 8 (gooi rest 1 weg) Uiteindelijk moet 35 >> 2 gelijk zijn aan 8. Laten we eens kijken:

public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
Console-uitgang: 8

Operatorvoorrang in Java

Tijdens het schrijven en lezen van code kom je vaak uitdrukkingen tegen die verschillende bewerkingen combineren. Het is erg belangrijk om de volgorde te begrijpen waarin ze worden uitgevoerd (anders zou je verrast kunnen zijn door het resultaat). Omdat Java veel bewerkingen heeft, heeft elk ervan een plaats gekregen in een speciale tabel:

Voorrang van de operator

Exploitanten Voorrang
postfix uitdr++ uitdr--
unair ++expr --expr +expr ~ !
Multiplicatief * / %
additief + -
verschuiving << >> >>>
relationeel < > <= >= exemplaar van
gelijkwaardigheid == !=
bitsgewijs EN &
bitsgewijze exclusieve OR ^
bitsgewijze inclusief OF |
logische EN &&
logische OF ||
ternair ? :
opdracht = += -= *= /= %= &= ^= |= <<= >>= >>>=
Alle bewerkingen worden van links naar rechts uitgevoerd, rekening houdend met hun prioriteit. Als we bijvoorbeeld schrijven

int x  = 6 - 4/2;
dan wordt eerst de deelbewerking ( 4/2 ) uitgevoerd. Hoewel het op de tweede plaats komt, heeft het een hogere prioriteit. Haakjes en haakjes geven maximale prioriteit aan. Dat herinner je je waarschijnlijk nog van school. Als u ze bijvoorbeeld toevoegt aan de uitdrukking

int x  = (6 - 4)/2;
dan wordt eerst de aftrekking uitgevoerd, aangezien deze tussen haakjes staat. De prioriteit van de logische && operator is vrij laag (zie de tabel), dus het zal meestal de laatste zijn. Bijvoorbeeld:

boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
Deze expressie wordt als volgt uitgevoerd:
  • 4/2 = 2

boolean x = 6 - 2 > 3 && 12*12 <= 119;
  • 12*12 = 144

boolean x = 6 - 2 > 3 && 144 <= 119;
  • 6-2 = 4

boolean x = 4 > 3 && 144 <= 119;
Vervolgens worden de vergelijkingsoperatoren uitgevoerd:
  • 4 > 3 = waar

boolean x = true && 144 <= 119;
  • 144 <= 119 = onwaar

boolean x = true && false;
En tot slot wordt de AND-operator ( && ) als laatste uitgevoerd.

boolean x = true && false;
boolean x = false;
De opteloperator ( + ) heeft bijvoorbeeld een hogere prioriteit dan de != (niet gelijk aan) vergelijkingsoperator; Daarom in de uitdrukking

boolean x = 7 != 6+1;
eerst wordt de 6+1-bewerking uitgevoerd, vervolgens de 7 != 7-controle (die resulteert in onwaar), en ten slotte de toewijzing van het resultaat (onwaar) aan de variabele x (toewijzing heeft over het algemeen de laagste prioriteit van alle operatoren; zie de tafel). Opluchting! Het was een enorme les, maar je hebt het gedaan! Maak je geen zorgen als je sommige van deze of vorige lessen niet helemaal hebt begrepen. We zullen deze onderwerpen in de toekomst meer dan eens behandelen. Een paar CodeGym-lessen over logische en numerieke bewerkingen. We zullen hier niet snel op terugkomen, maar het kan geen kwaad als u ze nu leest.
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION