JavaRush /Java-Blog /Random-DE /Bitweise Operationen in Java

Bitweise Operationen in Java

Veröffentlicht in der Gruppe Random-DE
Sie kennen wahrscheinlich das Wort „Beat“. Wenn nicht, lernen wir es kennen :) Ein Bit ist die kleinste Maßeinheit für Informationen in einem Computer. Sein Name kommt vom englischen „ binary digit “ – „Binärzahl“. Ein Bit kann als eine von zwei Zahlen ausgedrückt werden: 1 oder 0. Es gibt ein spezielles Zahlensystem, das auf Einsen und Nullen basiert – binär. Wir werden nicht in den Dschungel der Mathematik eintauchen und nur darauf hinweisen, dass jede Zahl in Java in ihre binäre Form umgewandelt werden kann. Dazu müssen Sie Wrapper-Klassen verwenden. Bitweise Operationen - 1So geht es beispielsweise für eine Zahl int:
public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
Konsolenausgabe:

101010110
1010 10110 (zur besseren Lesbarkeit habe ich ein Leerzeichen hinzugefügt) ist die Zahl 342 im Binärformat. Wir haben diese Zahl tatsächlich in einzelne Bits unterteilt – Nullen und Einsen. Mit ihnen können wir Operationen namens bitweise ausführen.
  • ~– bitweiser „NOT“-Operator.

Es funktioniert ganz einfach: Es geht jedes Bit unserer Zahl durch und ändert seinen Wert in das Gegenteil: Nullen in Einsen, Einsen in Nullen. Wenn wir es auf unsere Zahl 342 anwenden, erhalten wir Folgendes: 101010110 – die Zahl 342 im Binärformat 010101001 – das Ergebnis des Ausdrucks ~342 Da eine int-Variable jedoch 4 Bytes benötigt, d. h. 32 Bit, tatsächlich wird die Zahl in der Variablen wie folgt gespeichert: 00000000 00000000 00000001 01010110- die Zahl 342 in einer Variablen vom Typ int in Java 11111111 11111111 11111110 10101001- das Ergebnis des Ausdrucks ~342 in Java Versuchen wir dies in der Praxis zu tun:
public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(~x));
   }
}
Konsolenausgabe:
11111111111111111111111010101001
  • &— bitweiser Operator „AND“

Wie Sie sehen, ist die Schreibweise dem logischen „AND“ ( &&) sehr ähnlich. &&Wie Sie sich erinnern, gibt der Operator truenur zurück, wenn beide Operanden wahr sind. Bitwise &funktioniert ähnlich: Es vergleicht zwei Zahlen Stück für Stück. Das Ergebnis dieses Vergleichs ist die dritte Zahl. Nehmen wir zum Beispiel die Zahlen 277 und 432: 100010101 – die Zahl 277 in Binärform 110110000 – die Zahl 432 in Binärform Als nächstes &vergleicht der Operator das erste Bit der oberen Zahl mit dem ersten Bit der unteren. Da es sich um einen „AND“-Operator handelt, ist das Ergebnis nur dann gleich 1, wenn beide Bits gleich 1 sind. In allen anderen Fällen ist das Ergebnis 0. 100010101 & 110110000 _______________ 100010000 - Ergebnis der Arbeit & Wir vergleichen zunächst die ersten Bits zweier Zahlen miteinander, dann zweite Bits, dritte usw. Wie Sie sehen können, waren nur in zwei Fällen beide Bits in den Zahlen gleich 1 (das erste und das fünfte Bit). Das Ergebnis aller anderen Vergleiche war 0. Daher haben wir am Ende die Zahl 100010000 erhalten. Im Dezimalsystem entspricht sie der Zahl 272. Schauen wir mal:
public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
Konsolenausgabe:

272
  • |- bitweises „ODER“. Das Funktionsprinzip ist das gleiche – wir vergleichen zwei Zahlen Stück für Stück. Erst jetzt, wenn mindestens eines der Bits gleich 1 ist, ist das Ergebnis gleich 1. Schauen wir uns die gleichen Zahlen an – 277 und 432:
100010101 | 110110000 _______________ 110110101 - das Ergebnis der Arbeit. | Hier ist das Ergebnis anders: Nur die Bits, die in beiden Zahlen Nullen waren, blieben Nullen. Das Ergebnis der Arbeit ist die Zahl 110110101. Im Dezimalsystem entspricht sie der Zahl 437. Überprüfen wir:
public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
Konsolenausgabe:

437
Wir haben alles richtig gezählt! :) :)
  • ^- Bitweises Exklusiv-ODER (auch bekannt als XOR)
Einen solchen Operator haben wir noch nie erlebt. Aber daran ist nichts Kompliziertes. Es sieht aus wie ein normales „oder“. Der Unterschied ist nur einer: Das gewöhnliche „oder“ gibt zurück, truewenn mindestens ein Operand wahr ist. Aber nicht unbedingt eines – wenn beides da ist true– dann das Ergebnis true. Das exklusive „Oder“ wird jedoch truenur zurückgegeben, wenn einer der Operanden wahr ist. Wenn beide Operanden wahr sind, wird ein reguläres „oder“ zurückgegeben true(„mindestens einer ist wahr“), ein exklusives „oder“ jedoch false. Deshalb heißt es exklusiv. Wenn Sie das Prinzip der vorherigen bitweisen Operationen kennen, können Sie die 277^432-Operation wahrscheinlich problemlos selbst durchführen. Aber lass es uns besser noch einmal gemeinsam herausfinden :) 100010101 ^ 110110000 _______________ 010100101 - das Ergebnis der Arbeit ^ Hier ist unser Ergebnis. Die Bits, die in beiden Zahlen gleich waren, gaben 0 zurück (die „Eins von“-Formel funktionierte nicht). Aber diejenigen, die ein Paar 0:1 oder 1:0 bildeten, wurden schließlich zu einer Einheit. Als Ergebnis haben wir die Zahl 010100101 erhalten. Im Dezimalsystem entspricht sie der Zahl 165. Mal sehen, ob wir richtig gerechnet haben:
public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
Konsolenausgabe:

165
Super! Alles ist genau so, wie wir es uns vorgestellt haben :) Jetzt ist es an der Zeit, sich mit den Operationen namens Bitverschiebungen vertraut zu machen. Der Name spricht im Prinzip für sich. Wir nehmen eine Zahl und verschieben ihre Bits nach links und rechts :) Mal sehen, wie es aussieht:

Nach links verschieben

Die Linksverschiebung von Bits wird durch das Vorzeichen angezeigt << . Beispiel:
public class Main {

   public static void main(String[] args) {
       int x = 64;//Bedeutung
       int y = 3;//Menge

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
In diesem Beispiel wird die Zahl x=64als Wert bezeichnet. Es sind seine Teile, die wir verschieben werden. Wir werden die Bits nach links verschieben (dies kann durch die Richtung des Vorzeichens bestimmt werden <<) Im Binärsystem ist die Zahl 64 = 1000000. Die Zahl y=3heißt Menge. Quantity beantwortet die Frage „Um wie viele Bits sollten die Bits einer Zahl nach rechts/links verschoben werden x?“ In unserem Beispiel werden wir sie um 3 Bits nach links verschieben. Um den Schaltvorgang klarer zu machen, schauen wir uns das Bild an. In unserem Beispiel verwenden wir Zahlen vom Typ int. Intbelegen 32 Bit Computerspeicher. So sieht unsere ursprüngliche Zahl 64 aus: Bitweise Operationen - 2Und jetzt nehmen wir im wahrsten Sinne des Wortes jedes unserer Bits und verschieben es um 3 Zellen nach links: Bitweise Operationen - 3Das ist, was wir haben. Wie Sie sehen können, haben sich alle unsere Bits verschoben und drei weitere Nullen wurden von außerhalb des Bereichs hinzugefügt. 3 – weil wir um 3 verschoben haben. Wenn wir um 10 verschoben hätten, würden 10 Nullen hinzugefügt. Der Ausdruck x << ybedeutet also „die Bits einer Zahl хum y Zellen nach links verschieben“. Das Ergebnis unseres Ausdrucks war die Zahl 1000000000, die im Dezimalsystem 512 entspricht. Schauen wir uns an:
public class Main {

   public static void main(String[] args) {
       int x = 64;//Bedeutung
       int y = 3;//Menge

       int z = (x << y);
       System.out.println(z);
   }
}
Konsolenausgabe:

512
Alles ist richtig! Theoretisch können Bits unbegrenzt verschoben werden. Aber da wir die Nummer haben int, stehen nur 32 Zellen zur Verfügung. Davon sind 7 bereits mit der Zahl 64 (1.000.000) belegt. Wenn wir also beispielsweise 27-mal nach links schalten, gerät unsere einzige Einheit außer Reichweite und „überschreibt“. Es bleiben nur Nullen übrig!
public class Main {

   public static void main(String[] args) {
       int x = 64;//Bedeutung
       int y = 26;//Menge

       int z = (x << y);
       System.out.println(z);
   }
}
Konsolenausgabe:

0
Wie wir erwartet hatten, ging die eine über die 32-Bit-Zellen hinaus und verschwand. Wir haben eine 32-Bit-Zahl erhalten, die nur aus Nullen besteht. Bitweise Operationen - 4Im Dezimalsystem entspricht es natürlich 0. Eine einfache Regel zum Merken von Linksverschiebungen: Bei jeder Linksverschiebung wird die Zahl mit 2 multipliziert. Versuchen wir zum Beispiel, das Ergebnis des Ausdrucks ohne Bilder mit Bits zu berechnen. 111111111 << 3 Wir brauchen um die Zahl 111111111 dreimal mit 2 zu multiplizieren. Als Ergebnis erhalten wir 888888888. Schreiben wir den Code und überprüfen ihn:
public class Main {

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

888888888

Rechtsverschiebungen

Sie sind durch das Schild gekennzeichnet >>. Sie machen dasselbe, nur in die andere Richtung! :) Lasst uns das Rad nicht neu erfinden und versuchen, dies mit der gleichen Zahl int 64 zu tun.
public class Main {

   public static void main(String[] args) {
       int x = 64;//Bedeutung
       int y = 2;//Menge

       int z = (x >> y);
       System.out.println(z);
   }
}
Bitweise Operationen – 5Bitweise Operationen – 6Durch die Verschiebung um 2 nach rechts gelangten die beiden extremen Nullstellen unserer Zahl aus dem Bereich und wurden gelöscht. Wir haben die Zahl 10000 erhalten, die im Dezimalsystem der Zahl 16 entspricht. Ausgabe an die Konsole:

16
Eine einfache Regel zum Merken von Rechtsverschiebungen: Jede Rechtsverschiebung dividiert durch zwei und verwirft den Rest. Das bedeutet zum Beispiel, 35 >> 2 dass wir 35 zweimal durch 2 dividieren und den Rest verwerfen müssen 35/2 = 17(Rest 1 verwerfen) 17:2 = 8(Rest 1 verwerfen) Die Summe 35 >> 2sollte gleich 8 sein. Überprüfen Sie:
public class Main {

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

8

Vorrang von Operationen in Java

Beim Schreiben oder Lesen von Code werden Sie häufig auf Ausdrücke stoßen, in denen mehrere Vorgänge gleichzeitig ausgeführt werden. Es ist sehr wichtig zu verstehen, in welcher Reihenfolge sie ausgeführt werden, da sonst das Ergebnis unerwartet sein kann. Da es in Java viele Operationen gibt, wurden sie alle in einer speziellen Tabelle zusammengefasst:

Vorrang des Operators

Betreiber Vorrang
Postfix expr++ expr--
einstellig ++expr --expr +expr ~ !
Multiplikativ * / %
Zusatzstoff + -
Schicht << >> >>>
relational < > <= >=Instanz von
Gleichwertigkeit == !=
bitweises UND &
bitweises Exklusiv-ODER ^
bitweises inklusives ODER |
logisches UND &&
logisches ODER ||
ternär ? :
Abtretung = += -= *= /= %= &= ^= |= <<= >>= >>>=
Alle Operationen werden von links nach rechts ausgeführt, jedoch unter Berücksichtigung ihrer Priorität. Wenn wir zum Beispiel schreiben: int x = 6 - 4/2; Zuerst wird die Divisionsoperation (4/2) durchgeführt. Obwohl sie an zweiter Stelle steht, hat sie höhere Priorität. Klammern oder eckige Klammern ändern jede Priorität auf Maximum. Du erinnerst dich wahrscheinlich noch aus der Schule daran. Wenn Sie sie beispielsweise zu einem Ausdruck hinzufügen: int x = (6 - 4)/2; Die Subtraktion wird zuerst durchgeführt, da sie in Klammern berechnet wird. Der logische Operator hat &&eine eher niedrige Priorität, wie aus der Tabelle ersichtlich ist. Daher wird es meistens zuletzt ausgeführt. Beispiel: boolean x = 6 - 4/2 > 3 && 12*12 <= 119; Dieser Ausdruck würde wie folgt ausgeführt:
  • 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;
  • Als nächstes werden die Vergleichsoperatoren ausgeführt:

    4 > 3 = true

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

    boolean x = true && false;
  • Und schließlich wird der letzte Operator ausgeführt &&.

    boolean x = true && false;

    boolean x = false;

    Der Additionsoperator ( +) hat beispielsweise eine höhere Priorität als der Vergleichsoperator !=(„ungleich“);

    Deshalb im Ausdruck:

    boolean x = 7 != 6+1;

    Zuerst wird die Operation 6+1 ausgeführt, dann die Prüfung 7!=7 (falsch) und am Ende wird das Ergebnis der falseVariablen zugewiesen x. Die Zuweisung hat im Allgemeinen die niedrigste Priorität aller Vorgänge – schauen Sie in der Tabelle nach.

Puh! Unser Vortrag war lang, aber du hast es geschafft! Wenn Sie einige Teile dieser und der vorherigen Vorlesungen nicht vollständig verstehen, machen Sie sich keine Sorgen, wir werden diese Themen in Zukunft mehr als einmal ansprechen. Hier sind einige nützliche Links für Sie:
  • Logische Operatoren – JavaRush-Vorlesung über logische Operationen. Wir werden so schnell nicht darauf zurückkommen, aber Sie können sie jetzt lesen, es wird nicht schaden
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION