Navigation überspringen

Operatoren Teil 2

Bitweise Operatoren

Zweierkomplementdarstellung

Bitweise Operatoren können in Java ausschleißlich auf numerische Operanden, sprich alle numerischen Datentypen, angewendet werden. Um die bitweisen Operatoren zu erklären verwenden wir hier den Datentyp byte.

Numerische Datentypen werden in Java binär und als Zweierkomplement interpretiert. Das Zweierkomplement ist eine Möglichkeit, negative Zahlen im Binärsystem darzustellen, ohne zusätzliche Zeichen wie + und zu benötigen.

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 denselben Wert wie bei der positiven Darstellung. Das höchstwertige Bit hingegen ist negativ.  Daher muss der Wert dieses Bits von dem Wert restlichen Bits abgezogen werden.

Schauen wir uns folgendes Beispiel an:

10000010

Das höchstwertige Bit ist eine 1, sprich es ist negativ. Statt für 128 steht es für -128.
Die restlichen Bits haben zusammen einen Wert von 2. Es ergibt sich folgende Rechnung: 2 - 128 = -126
In der Zweierkomplementdarstellung hat die oben abgebildete Bitfolge also den Wert -126.

Schau dir die Tabelle an. Dort findest du ein paar wichtige Zahlenwerte zur Veranschaulichung des eben erklärten:

Binärwert

Interpretation als
Zweierkomplement

 Binärwert Interpretation als
Zweierkomplement
 Binärwert Interpretation als
Zweierkomplement
 Binärwert Interpretation als
Zweierkomplement
00000000 0 01111110 126 10000000 -128 11111110 -2
00000001 1 01111111 127 10000001 -127 11111111 -1
10000010 -126

Operatoren

Bitweise Operatoren werden in Java verwendet, um Binärwerte bitweise zu manipulieren. Die folgenden bitweisen Operatoren gibt es in Java:

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

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 Processing kannst du dir eine Variable in binär anzeigen lassen mithilfe der binary() Funktion.

int wert = 3;
println(wert); 
println(binary(wert)); 
3
00000000000000000000000000000011
WICHTIG: Die Funktion binary() liefert dir einen String zurück! Du kannst sie also nicht verwenden, um eine Zahl in einer Binärzahl umzuwandeln. Es gibt auch das Gegenstück zu dieser Funktion: unbinary(). Diese Funktion nimmt einen Binär-String als Parameter und liefert einen Integer-Wert zurück.

Ternärer Operator

Ein Operator mit drei Operandenstellen ist ein ternärer Operator.  In Java gibt es genau einen ternären Operator, welcher deswegen auch der ternäre Operator genannt wird. Er ist der einzige Operator, der mit drei Operanden arbeitet und wird oft auch Bedingungsoperator genannt.

Der Bedingungsoperator hat folgenden allgemeinen Aufbau:

bedingung ? wert1 : wert2

bedingung muss immer ein boolescher Ausdruck sein. Er entscheidet über die Wertzuweisung. Ist er true , so wird der Wert nach dem Fragezeichen zugewiesen, ansonsten der Wert nach dem Doppelpunkt.

Die Variablenzuweisung erfolgt dann in der Form

variable = bedingung ? wert1 : wert2

Stell dir vor du schreibst ein Programm, das auswerten soll, ob Studierende eine Klausur bestanden haben. Bestanden haben sie, wenn sie mehr als 50 Punkte haben. Das sieht wiefolge aus:

int punkte = 76;
            String msg = punkte >= 50 ? "Bestanden" : "Nicht bestanden";
            println(msg);

Je nachdem, welchen Wert punkte hat, nimmt msg den Wert "Bestanden" oder "Nicht bestanden" an.

Rangfolge der Operatoren

Operatoren werden in Java nach einer festen Reihenfolge ausgewertet. Operatoren mit einem höheren Rang haben Vorrang vor Operatoren mit einem niedrigeren Rang. Dies wird auch als Vorrangregel oder Bindungsregel bezeichnet.

In Java hat jeder Operator eine gewisse Bindungskraft. Der Multiplikations-Operator hat z.B. eine höhere Bindungskraft als der Additions-Operator und wird somit zuerst ausgewertet. Ähnlich wie die Regel in Mathe: Punkt vor Strich.

Manchmal besitzen Operatoren die selbe Bindungskraft. In so einem Fall entscheidet die Assoziativität über die Reihenfolge der Auswertung. Der Additions– und Subtraktions-Operator haben z.B. die gleiche Bindungskraft. Werden sie aber in einer Kette von Additionen und Subtraktionen verwendet, bestimmt ihre Assoziativität über die Auswertungsreihenfolge. In diesem Fall sind beide Operatoren linksassoziativ, daher wird der Ausdruck von links nach rechts ausgewertet.

Daher wird a+b-c wie (a+b)-c ausgewertet und nicht wie a+(b-c).

In der folgenden Tabelle sind alle Java-Operatoren in Gruppen zusammengefasst.

Die Gruppenummer entspricht dem Rang des jeweiligen Operators. Gruppe eins enthält die Java-Operatoren mit dem höchsten Rang. Die Assoziativität gibt an, ob ein Operator von links nach rechts oder von rechts nach links ausgewertet wird.

Gruppe Operator Beispiel Bezeichnung Assoziativität Beschreibung
1 ++
--
a++
a--
Postinkrement
Postdekrement
Rechts Beim Postinkrement wird dem übergeordneten Ausdruck der ursprüngliche Wert von a übergeben. Anschließend wird a um 1 erhöht.
Beim Postdekrement wird dem übergeordneten Ausdruck der ursprüngliche Wert von a übergeben. Anschließend wird a um 1 verringert.

++
--

++a
--a
Präinkrement
Prädekrement
Rechts Beim Präinkrement wird dem übergeordneten Ausdruck der um 1 erhöhte Wert von a übergeben.
Beim Prädekrement wird dem übergeordneten Ausdruck der um 1 verringerte Wert von a übergeben.
+
-
+a
-a
Positives/negatives Vorzeichen Rechts Nicht zwingend, da +a dem gleichen Wert wie a entspricht. 
Entspricht dem negativem Wert von a.
~ ~a Einerkomplement Rechts Es werden alle Bits von a invertiert, das heißt aus 0 wird 1 und umgekehrt.
! !a Logisches Nicht Rechts Es wird a negiert. Ist a wahr, wird false zurückgegeben, andernfalls true.
(type) (int) a Type-Cast Rechts Der Datentyp von a wird in den in Klammern angegebenen Datentyp umgwandelt.
2 *
/
%
a*b
a/b
a%b
Multiplikation
Division
Modulo
Links Aus der Multiplikation von a mal b ergibt sich das Produkt.
Aus der Division von a durch b ergibt sich der Quotient.
Aus Modulo von a durch b ergibt sich der Rest.
3 +
-
a + b
a – b
Addition
Subtraktion
Links  Aus der Addition von a plus b ergibt sich die Summe.
Aus der Subtraktion von a minus b ergibt sich die Differenz.
+ „A“ + b String-Verkettung Links  Ein String wird mit einem anderen String angefügt. Wenn nötig wird dabei der Wert in einen String umgewandelt.
4 << a << b Linksschieben Links  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.
>> a >> b Rechtsschieben
mit Vorzeichen (arithmetisch)
Links  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.
>>> a >>> b Rechtsschieben
ohne Vorzeichen (logisch)
Links  Es werden die Bits von a um b Positionen nach rechts geschoben. Das höchstwertige Bit wird nach dem Schieben immer auf 0 gesetzt.
5 <
>
a < b
a > b
Kleiner als
Größer als
Links  Es wird a mit b verglichen. Ist a kleiner als b wird true zurückgegeben, andernfalls false.
Es wird a mit b verglichen. Ist a größer als b wird true zurückgegeben, andernfalls false.
<=
>=
a <= b
a >= b
Kleiner gleich
Größer gleich
Links  Es wird a mit b verglichen. Ist a kleiner als oder gleich b wird true zurückgegeben, andernfalls false.
Es wird a mit b verglichen. Ist a größer als oder gleich b wird true zurückgegeben, andernfalls false.
6 == a == b Gleich Links  Es wird a mit b verglichen. Ist a gleich b wird true zurückgegeben, andernfalls false. Wenn a und b Referenztypen sind, wird verglichen ob beide Variablen auf das gleiche Objekt referenzieren. Falls ja, wird true zurückgegeben.
!= a != b Ungleich Links  Es wird a mit b verglichen. Ist a ungleich b wird true zurückgegeben, andernfalls false. Wenn a und b Referenztypen sind, wird verglichen ob beide Variablen auf verschiedene Objekte referenzieren. Falls ja, wird true zurückgegeben.
7 & a & b Und (bitweise) Links Es wird a und b bitweise ausgewertet. Dabei wird jedes korrespondierende Bit von a und b miteinander Und-verknüpft.
& a & b Und (logisch) Links Es wird a und b ausgewertet. Sind beide wahr, wird true zurückgegeben, andernfalls false.
8 ^ a ^ b Exklusiv-Oder (bitweise) Links Es wird a und b bitweise ausgewertet. Dabei wird jedes korrespondierende Bit von a und b miteinander Exklusiv-Oder-verknüpft.
^ a ^ b Exklusiv-Oder (logisch) Links Es wird a und b ausgewertet. Besitzt a einen anderen Wahrheitswert als b wird true zurückgegeben, andernfalls false.
9 | a | b Oder (bitweise) Links Es wird a und b bitweise ausgewertet. Dabei wird jedes korrespondierende Bit von a und b miteinander Oder-verknüpft.
| a | b Oder (logisch) Links Es wird a und b ausgewertet. Ist mindestens einer der beiden Ausdrücke wahr, wird true zurückgegeben, andernfalls false.
10 && a && b Und (S-C-E) Links Es wird a und b ausgewertet. Die Auswertung wird abgebrochen wenn a bereits falsch ist. Dann wird sofort false zurückgegeben. Sind beide wahr, wird true zurückgegeben, andernfalls false.
11 || a || b Oder (S-C-E) Links Es wird a und b ausgewertet. Die Auswertung wird abgebrochen wenn a bereits wahr ist. Dann wird sofort true zurückgegeben. Ist mindestens einer der beiden Ausdrücke wahr, wird true zurückgegeben, andernfalls false.
12 ?: c ? a:b Bedingte Auswertung Rechts Falls die Bedingung c wahr ist, wird der Wert von a zurückgegeben. Andernfalls, wird der Wert von b zurückgegeben.
13 = a = b Einfache Zuweisung Rechts Es wird a der Wert von b zugewiesen und b als Rückgabewert geliefert.
+=
-=
*=
/=
%=
a += b
a -= b
a *= b
a /= b
a %= b
Additions-zuweisung
Subtraktions-zuweisung
Multiplikations-zuweisung
Divisions-zuweisung
Modulo-zuweisung
Rechts  Es wird a das Ergebnis aus a + b zugewiesen und a + b als Rückgabewert geliefert.
Es wird a das Ergebnis aus a – b zugewiesen und a – b als Rückgabewert geliefert.
Es wird a das Ergebnis aus a * b zugewiesen und a * b als Rückgabewert geliefert.
Es wird a das Ergebnis aus a / b zugewiesen und a / b als Rückgabewert geliefert.
Es wird a das Ergebnis aus a % b zugewiesen und a % b als Rückgabewert geliefert.
&=
|=
a &=b
a |= b
Und-Zuweisung
Oder-Zuweisung
 Es wird a das Ergebnis aus a & b zugewiesen und a & b als Rückgabewert geliefert.
Es wird a das Ergebnis aus a | b zugewiesen und a | b als Rückgabewert geliefert.
<<= a <<= b Linksschiebe-Zuweisung  Es wird a das Ergebnis aus a << b zugewiesen und a << b als Rückgabewert geliefert.
>>= a >>= b Rechtsschiebe-Zuweisung mit  Vorzeichen  Es wird a das Ergebnis aus a >> b zugewiesen und a >> b als Rückgabewert geliefert.
>>>= a >>>= b Rechtsschiebe-Zuweisung ohne Vorzeichen  Es wird a das Ergebnis aus a >>> b zugewiesen und a >>> b als Rückgabewert geliefert.

Zusammenfassung

  • Binäre Zahlen werden in Java als Zweierkomplement interpretiert. Dies ist eine Schreibweise, bei der das höchstwertige Bit genutzt wird, um darzustellen, ob es sich um eine negative oder eine positive Zahl handelt.
  • Bitweise Operatoren rechnen mit und verarbeiten Binärzählen. Es gibt in Java 7 bitweise Operatoren:
    • Einerkomplement: ~
    • Bitweises Und: &
    • Bitweises Oder: |
    • Bitweises Exklusiv-Oder: ^
    • Linksschiebung (arithmetisch): <<
    • Rechtschiebung (ohne Vorzeichen): >>
  • Der Ternäre Operator ist der sogenannte Bedinungsoperator. Mit ihm kann man eine Bedinung prüfen und je nach Ergebnis einer Variablen einen Wert zuweisen.
variable = bedingung ? wert1 : wert2
  • Operatoren haben in Java eine Rangfolge, die entscheidet, welcher Operator zuerst angewendet wird.
    • Es gibt zwei wichtige Faktoren, welche über die Rangfolge entscheiden: Zuerst die Bindungskraft und danach die Assoziativität (Richtung).

Made with eXeLearning (New Window)