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 a
ist die Zahl, deren Bits verschoben werden, und b
ist eine Zahl, die angibt, wie oft die Bits der Zahl a
nach links verschoben werden sollen. Während dieser Operation sind die rechts hinzugefügten niederwertigen Bits Nullen.
Beispiele:
Beispiel | Ergebnis |
---|---|
|
|
|
|
|
|
|
|
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 a
ist die Zahl, deren Bits verschoben werden, und b
wie oft werden die Bits der Zahl a
nach rechts verschoben?
Beispiele:
Beispiel | Ergebnis |
---|---|
|
|
|
|
|
|
|
|
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 !
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 1
erhält dieses Bit bei negativen Zahlen (wobei das Bit ganz links ist) eine Sonderbehandlung. Beim Verschieben der Bits einer Zahl nach rechts 0
wird a links hinzugefügt, wenn das Bit ganz links war 0
, und a 1
links hinzugefügt, wenn das Bit ganz links war 1
.
Aber im obigen Beispiel scheint das nicht das Ergebnis zu sein. Warum? Weil ganzzahlige Literale int
s sind und tatsächlich bedeuten . Das heißt, das Bit ganz links ist Null.0b11111111
0b00000000000000000000000011111111
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 a
nach 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 ( true
oder false
) Werte speichern müssen. Ein Single long
ist wie ein boolean
Array 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 0b00001010
und 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 1
außer gleich sind für das Bit, das Sie zurücksetzen möchten.
Angenommen, Sie haben die Nummer 0b00001010
und 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 1
außer dem einen, das wir Null haben wollen, sind, verschieben wir zunächst 1 b- Positionen nach links und NOT
invertieren 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 1
in 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 XOR
Operation 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 XOR
zweimaliger 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));
}
}
GO TO FULL VERSION