Java-Grundlagen: Bitweise Operatoren in Java

In Java können bitweise Operatoren nur auf numerische Operanden angewendet werden. Als mögliche Operanden kommen alle numerischen Datentypen in Frage. Wir werden in diesem Beispiel den einfachsten numerischen Datentyp, den byte-Datentyp, zur Erklärung der bitweisen Operatoren nutzen.

Die numerischen Datentypen werden in Java binär interpretiert, wobei das höchste Bit das Vorzeichen darstellt.

In der Tabelle rechts sind einige wichtige Zahlenwerte eingetragen. Dabei fällt auf, dass der Binärwert einmal als Zweierkomplement und einmal als vorzeichenlose Zahl interpretiert wird.

Binärwert Interpretation als Zweierkomplement Interpretation als vorzeichenlose Zahl
00000000 0 0
00000001 1 1
~~~ ~~~ ~~~
01111110 126 126
01111111 127 127
10000000 -128 128
10000001 -127 129
10000010 -126 130
~~~ ~~~ ~~~
11111110 -2 254
11111111 -1 255

In Java werden numerische Datentypen als Zweierkomplement interpretiert. Dieser Sachverhalt ist für jeden Java- Programmierer von größter Bedeutung, wenn es um die bitweise Manipulation von numerischen Daten geht.

Ist das höchstwertige Bit gesetzt (= 1), liegt eine negative Zahl vor.

Die Zweierkomplementdarstellung ist am einfachsten wie folgt zu erklären: Alle Bits haben die gleiche Wertigkeit wie bei der positiven Darstellung. Jedoch besitzt das höchstwertige Bit (MSB = most significant bit) eine negative Wertigkeit. Daher muss der Wert dieses Bits von dem Wert der rechtsstehenden Bitfolge abgezogen werden.

Am Beispiel von 10000010 ergibt sich: -128 da das höchstwertige Bit gesetzt ist und 2 aus der rechtsstehenden Bitfolge 0000010. Subtrahiert man -128 von 2, erhält man als Ergebnis -126.

Bitweise Operatoren in Java

Die Hauptaufgabe von bitweisen Operatoren in Java besteht darin, Binärwerte bitweise zu manipulieren. Besonders wichtige bitweise Operatoren sind die Schiebe-Operatoren, die auch in vielen anderen Programmiersprachen wiederzufinden sind.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Die folgenden bitweisen Operatoren sind in Java definiert:

  • Einerkomplement-Operator
  • Bitweise Logische Verknüpfungs-Operatoren
  • Schiebe-Operator

Hinweis: In Java sind alle numerischen Datentypen vorzeichenbehaftet, ihr höchtwertiges Bit gibt an ob die Zahl positiv oder negativ ist. Ist das höchstwertige Bit gesetzt (= 1), ist die Zahl negativ. Der zusätzliche Rechtsschiebe-Operator >>> setzt nach dem Verschieben der Bits das höchstwertige Bit immer auf 0. Somit ist die resultierende Zahl stets positiv. Aufpassen! Dies funktioniert nur für int-Datentypen (Operanden) reibungslos.

Die folgende Tabelle stellt die bitweisen Operatoren von Java einzeln vor:

Operator Bezeichnung Beispiel Beschreibung
~ Einerkomplement ~a Es werden alle Bits von a invertiert, das heißt aus 0 wird 1 und umgekehrt.
& Bitweises Und a & b Es wird a und b bitweise ausgewertet. Dabei wird jedes korrespondierende Bit von a und b miteinander Und-verknüpft.
| Bitweises Oder a | b Es wird a und b bitweise ausgewertet. Dabei wird jedes korrespondierende Bit von a und b miteinander Oder-verknüpft.
^ Bitweises Exklusiv-Oder a ^ b Es wird a und b bitweise ausgewertet. Dabei wird jedes korrespondierende Bit von a und b miteinander Exklusiv-Oder-verknüpft.
<< Linksschieben a << b Es werden die Bits von a um b Positionen nach links geschoben. Auch das höchstwertige Bit wird nach links geschoben und erfährt keine besondere Behandlung.
>> Rechtsschieben
mit Vorzeichen
(arithmetisch)
a >> b Es werden die Bits von a um b Positionen nach rechts geschoben. Das höchstwertige Bit wird nach dem Schieben gesetzt, falls es auch vor dem Schieben gesetzt war. Somit bleibt eine negative Zahl auch nach dem Rechtsschieben negativ.
>>> Rechtsschieben
ohne Vorzeichen
(logisch)
a >>> b Es werden die Bits von a um b Positionen nach rechts geschoben. Das höchstwertige Bit wird nach dem Schieben immer auf 0 gesetzt.

In dem folgenden Beispielprogramm werden die bitweisen Operatoren verwendet.

Bei negativen Zahlen muss extrem aufgepasst werden. Der logische Rechtsschiebe-Operator birgt besondere Risiken die zu schweren Programmierfehlern führen können.

Solange die Schiebe-Operatoren auf int-Datentypen anwendet werden, ergeben sich leicht nachvollziehbare Ergebnisse. Werden die Schiebe-Operatoren jedoch auf kleinere Datentypen bspw. byte-Datentypen angewendet, muss der Programmierer genau wissen was er tut.

Die Verschiebung wird immer mit int-Werten durchgeführt. Dadurch werden zwar bei dem logischen Rechtsschiebe-Operator Nullen vorne angefügt, aber eben ganz links am 32ten Bit. Durch eine Typumwandlung von int zu byte werden nur die letzten 8 Bit behalten. Die vorne angefügten Nullen gehen somit verloren.

In dem Quelltextbeispiel kann man dieses Verhalten in Ruhe analysieren. Siehe Quelltext Zeile 57 bis 75 und die dazugehörige Kommandozeilenausgabe weiter unten.

Beispiel bitweise Operatoren in Java.

/*
* Beispielanwendung bitweise Operatoren in Java.
*/

public class BitweiseOperatoren{
 public static void main(String[] args) {
 
  byte a = 0b00101011, b = (byte) 0b10110111;
  byte e;
  int e2;

  System.out.println("\na = " + a);
  binaerDarstellenVonByte("a = ", a);
  System.out.println("\nb = " + b);
  binaerDarstellenVonByte("b = ", b);

  e = (byte) ~a;
  System.out.println("\nEinerkomplement von a: ~a = " + e);
  binaerDarstellenVonByte("a als Byte = ", a);
  binaerDarstellenVonByte("~a         = ", e);

  e = (byte) (a & b);
  System.out.println("\nBitweises Und von a und b: a & b = " + e);
  binaerDarstellenVonByte("a als Byte = ", a);
  binaerDarstellenVonByte("b als Byte = ", b);
  binaerDarstellenVonByte("a & b      = ", e);

  e = (byte) (a | b);
  System.out.println("\nBitweises Oder von a und b: a | b = " + e);
  binaerDarstellenVonByte("a als Byte = ", a);
  binaerDarstellenVonByte("b als Byte = ", b);
  binaerDarstellenVonByte("a | b      = ", e);

  e = (byte) (a ^ b);
  System.out.println("\nBitweises Exklusiv-Oder von a und b: a ^ b = " + e);
  binaerDarstellenVonByte("a als Byte = ", a);
  binaerDarstellenVonByte("b als Byte = ", b);
  binaerDarstellenVonByte("a ^ b      = ", e);

  e = (byte) (a << 3);
  System.out.println("\nLinksschieben a um 3 Positionen: a << 3 = " + e);
  binaerDarstellenVonByte("a als Byte = ", a);
  binaerDarstellenVonByte("a << 3     = ", e);

  e = (byte) (a >> 3);
  System.out.println("\nArithm. Rechtsschieben a um 3 Pos.: a >> 3 = " + e);
  binaerDarstellenVonByte("a als Byte = ", a);
  binaerDarstellenVonByte("a >> 3     = ", e);

  e2 = a >>> 3;
  System.out.println("\nLog. Rechtsschieben a um 3 Pos.: a >>> 3 = " + e2);
  binaerDarstellenVonInt("a als Int  = ", a);
  binaerDarstellenVonInt("a >>> 3    = ", e2);

  System.out.println("\n ---");

  e = (byte) (b >> 3);
  System.out.println("\nArithm. Rechtsschieben b um 3 Pos.: b >> 3 = " + e);
  binaerDarstellenVonByte("b als Byte = ", b);
  binaerDarstellenVonByte("b >> 3     = ", e);

  e2 = b >> 3;
  System.out.println("\nArithm. Rechtsschieben b um 3 Pos.: b >> 3 = " + e2);
  binaerDarstellenVonInt("b als Int  = ", b);
  binaerDarstellenVonInt("b >> 3     = ", e2);

  e = (byte) (b >>> 3);
  System.out.println("\nLog. Rechtsschieben b um 3 Pos.: b >>> 3 = " + e);
  binaerDarstellenVonByte("b als Byte = ", b);
  binaerDarstellenVonByte("b >>> 3    = ", e);

  e2= b >>> 3 ;
  System.out.println("\nLog. Rechtsschieben b um 3 Pos.: b >>> 3 = " + e2);
  binaerDarstellenVonInt("b als Int  = ", b);
  binaerDarstellenVonInt("b >>> 3    = ", e2);

 }

 public static void binaerDarstellenVonByte (String text, byte zahl) {
  
  byte maske = 0b00000001;
  char[] bitfolge = new char[8];

  for (int i = 0; i < 8; i++) 
  {
   bitfolge[7 - i] = (zahl & maske) == 0 ? '0' : '1';
   maske = (byte) (maske << 1);
  }

  System.out.print(text);
  System.out.println(bitfolge);
 }

 public static void binaerDarstellenVonInt (String text, int zahl) {
  
  int maske = 0b00000000000000000000000000000001;
  char[] bitfolge = new char[32];

  for (int i = 0; i < 32; i++) 
  {
   bitfolge[31 - i] = (zahl & maske) == 0 ? '0' : '1';
   maske = maske << 1;
  }

  System.out.print(text);
  System.out.println(bitfolge);
 }
}

Die zugehörige Textausgabe ist in der unten abgebildeten Kommandozeilenausgabe dargestellt.

Java bitweise Operatoren in Ausgabe

Java bitweise Operatoren – Ausgabe der Beispielanwendung


Comments 4

  1. Pingback: Operatoren, Ausdrücke und Anweisungen in Java -

  2. Pingback: Java-Grundlagen: Besondere Operatoren in Java

  3. Pingback: Java-Grundlagen: Zuweisungsoperatoren in Java

  4. Pingback: Java-Grundlagen: Ausdrücke, die kleinsten ausführbaren Einheiten in Java

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.