1. Bitweise Linksverschiebung

Java verfügt außerdem über drei bitweise Verschiebungsoperatoren : Wenn es wirklich nötig ist, können Sie ganz einfach alle Bits einer Zahl um mehrere Positionen nach links oder rechts verschieben.

Um die Bits einer Zahl nach links zu verschieben, benötigen Sie den bitweisen Linksverschiebungsoperator . So steht es geschrieben:

a << b

Wo aist die Zahl, deren Bits verschoben werden, und bist eine Zahl, die angibt, wie oft die Bits der Zahl anach links verschoben werden sollen. Während dieser Operation sind die rechts hinzugefügten niederwertigen Bits Nullen.

Beispiele:

Beispiel Ergebnis
0b00000011 << 1
0b00000110
0b00000011 << 2
0b00001100
0b00000011 << 5
0b01100000
0b00000011 << 20
0b001100000000000000000000

Das Verschieben einer Ziffer nach links hat den gleichen Effekt wie das Multiplizieren einer Zahl mit 2.

Möchten Sie eine Zahl mit 16 multiplizieren? 16 ist dasselbe wie 2 4 . Man verschiebt also die Zahl um 4 Stellen nach links


2. Bitweise Verschiebung nach rechts

Bits können auch nach rechts verschoben werden. Verwenden Sie dazu den bitweisen Rechtsverschiebungsoperator . So steht es geschrieben:

a >> b

Wo aist die Zahl, deren Bits verschoben werden, und bwie oft werden die Bits der Zahl anach rechts verschoben?

Beispiele:

Beispiel Ergebnis
0b11000011 >> 1
0b01100001
0b11000011 >> 2
0b00110000
0b11000011 >> 5
0b00000110
0b11000011 >> 20
0b00000000

Das Verschieben einer Ziffer nach rechts hat den gleichen Effekt wie das Teilen einer Zahl durch 2.

Während dieser Operation sind die links hinzugefügten höherwertigen Bits Nullen, aber nicht immer !

Wichtig!

Das Bit ganz links einer vorzeichenbehafteten Zahl wird als Vorzeichenbit bezeichnet : Wenn die Zahl positiv ist, ist sie es 0; aber wenn die Zahl negativ ist, ist dieses Bit 1.

Beim Verschieben der Bits einer Zahl nach rechts verschiebt sich normalerweise auch der Wert des Vorzeichenbits und das Vorzeichen der Zahl geht verloren. Dementsprechend 1erhält dieses Bit bei negativen Zahlen (wobei das Bit ganz links ist) eine Sonderbehandlung. Beim Verschieben der Bits einer Zahl nach rechts 0wird a links hinzugefügt, wenn das Bit ganz links war 0, und a 1links hinzugefügt, wenn das Bit ganz links war 1.

Aber im obigen Beispiel scheint das nicht das Ergebnis zu sein. Warum? Weil ganzzahlige Literale ints sind und  tatsächlich bedeuten . Das heißt, das Bit ganz links ist Null.0b111111110b00000000000000000000000011111111

Viele Programmierer sind über dieses Rechtsverschiebungsverhalten frustriert und würden es vorziehen, wenn die Zahl immer mit Nullen aufgefüllt würde. Deshalb hat Java einen weiteren Rechtsverschiebungsoperator hinzugefügt .

So steht es geschrieben:

a >>> b

Wo a ist die Zahl, deren Bits verschoben werden, und b  wie oft werden die Bits der Zahl anach rechts verschoben? Dieser Operator hängt immer links Nullen an, unabhängig vom ursprünglichen Wert des Vorzeichenbits der Zahl a.



3. Arbeiten mit Flaggen

Programmierer haben auf der Grundlage bitweiser Operationen und Verschiebungsoperationen ein fast völlig neues Forschungsgebiet geschaffen: die Arbeit mit Flags.

Als Computer noch über sehr wenig Speicher verfügten, war es sehr beliebt, viele Informationen in einer einzigen Zahl zusammenzupacken. Eine Zahl wurde als Array von Bits behandelt: Ein int ist 32 Bits und ein long ist 64 Bits.

In eine solche Zahl können Sie viele Informationen schreiben, insbesondere wenn Sie logische ( trueoder false) Werte speichern müssen. Ein Single longist wie ein booleanArray bestehend aus 64 Elementen. Diese Bits wurden Flags genannt und mit den folgenden Operationen manipuliert:

  • Flagge setzen
    (ein bestimmtes Bit gleich machen 1)
  • Reset-Flag
    (ein bestimmtes Bit gleich machen 0)
  • Check-Flag
    (überprüfen Sie den Wert eines bestimmten Bits)

Und so wird es mit bitweisen Operatoren gemacht.

Setzen einer Flagge

Um ein bestimmtes Bit auf zu setzen 1, müssen Sie eine bitweise ODER-Verknüpfung zwischen der Zahl, deren Bit Sie setzen möchten, und einer speziell erstellten Zahl durchführen, bei der nur dieses Bit ist 1.

Angenommen, Sie haben die Nummer 0b00001010und müssen das 5. Bit auf setzen 1. In diesem Fall müssen Sie:

0b00001010 | 0b00010000 = 0b00011010

Wenn das 5. Bit bereits auf Eins gesetzt wäre, hätte sich nichts geändert.

Im Allgemeinen kann der Vorgang zum Setzen eines Flags wie folgt geschrieben werden

a | (1 << b)

Wo a ist die Zahl, deren Bit auf gesetzt wird 1? Und b ist die Position des zu setzenden Bits. Die Verwendung des linken Shift-Operators ist hier sehr praktisch, da Sie sofort erkennen können, mit welchem ​​Bit wir arbeiten.

Zurücksetzen einer Flagge

Um ein bestimmtes Bit zurückzusetzen (d. h. auf 0) zu setzen, ohne andere Bits zu stören, müssen Sie eine &Operation zwischen der Zahl, deren Bit Sie zurücksetzen (d. h. auf 0) setzen möchten, und einer speziell erstellten Zahl durchführen, bei der alle Bits 1außer gleich sind für das Bit, das Sie zurücksetzen möchten.

Angenommen, Sie haben die Nummer 0b00001010und müssen das 4. Bit auf setzen 0. In diesem Fall müssen Sie:

0b00001010 & 0b11110111 = 0b00000010

Wenn das 4. Bit bereits auf Null gesetzt wäre, hätte sich nichts geändert.

Im Allgemeinen kann der Vorgang zum Zurücksetzen eines Flags wie folgt geschrieben werden

a & ~(1 << b)

Wo a ist die Nummer, deren Bit auf zurückgesetzt wird 0? Und b ist die Position des zu löschenden Bits.

Um eine Zahl zu erhalten, bei der alle Bits 1außer dem einen, das wir Null haben wollen, sind, verschieben wir zunächst 1 b-  Positionen nach links und NOTinvertieren das Ergebnis dann mit dem bitweisen Operator.

Überprüfung einer Flagge

Zusätzlich zum Setzen oder Zurücksetzen eines bestimmten Flags muss manchmal nur überprüft werden, ob ein bestimmtes Flag gesetzt ist, dh ob ein bestimmtes Bit gleich ist 1. Das geht ganz einfach mit einer bitweisen &.

Angenommen, Sie müssen überprüfen, ob das 4. Bit 1in der Zahl auf gesetzt ist 0b00001010. Dann müssen Sie Folgendes tun:

if ( (0b00001010 & 0b00001000) == 0b00001000 )

Im Allgemeinen kann die Operation zum Überprüfen eines Flags wie folgt geschrieben werden

(a & (1 << b)) == (1 << b)

Wo a ist die Nummer, deren Bit überprüft wird? Und b ist die Position des zu prüfenden Bits.


4. Verschlüsselung

Die bitweise XOROperation wird von Programmierern häufig zur einfachen Verschlüsselung verwendet. Im Allgemeinen sieht eine solche Verschlüsselung so aus:

result = number ^ password;

Wo number sind die Daten, die wir verschlüsseln möchten, password ist eine spezielle Nummer, die als „Passwort“ für die Daten verwendet wird, und result ist die verschlüsselte Nummer?

number == (number ^ password) ^ password;

Wichtig hierbei ist, dass bei XORzweimaliger Anwendung des Operators auf eine Nummer unabhängig vom „Passwort“ die ursprüngliche Nummer ausgegeben wird.

Um number den Fehler zu beheben encrypted result, müssen Sie nur den Vorgang erneut ausführen:

original number = result ^ password;

Beispiel:

class Solution
{
   public static int[] encrypt(int[] data, int password)
   {
     int[] result = new int[data.length];
     for (int i = 0; i <  data.length; i++)
       result[i] = data[i] ^ password;
     return result;
   }

   public static void main(String[] args)
   {
     int[] data =  {1, 3, 5, 7, 9, 11};
     int password = 199;

     // Encrypt the array of data
     int[] encrypted = encrypt(data, password);
     System.out.println(Arrays.toString(encrypted));

     // Decrypt the array of data
     int[] decrypted = encrypt(encrypted, password);
     System.out.println(Arrays.toString(decrypted));
   }
}