ein Kapitel zurück                                           ein Kapitel weiter

Kommen wir nun zu den Bitweisen Operatoren. Als erstes will zur Einfachheit das Kapitel dazu etwas theoretischer halten.

Binären AND-Operator &

Sehen wir uns mal folgendes Programm an....

/*Download:b_and.c*/
#include <stdio.h> int main() { int x=55; printf("x=%d\n",x); x= x&7; printf("x=%d\n",x); return 0; }

Wenn sie das Programm ausgeführt haben werden sie sich sicher fragen warum der Wert von x durch...

x= x&7;  

nun 7 ist? Schauen wir uns doch mal die Bitdarstellung der beiden Zahlen an...

Bitnummer: 7 6 5 4 3 2 1 0
55 0 0 1 1 0 1 1 1
&7 0 0 0 0 0 1 1 1
=7 0 0 0 0 0 1 1 1
Bit-Wert: 128 64 32 16 8 4 2 1


An dieser Tabelle können sie erkennen das alle Bitnummern bei der beide auf 1 stehen weiterhin auf 1 stehen bleiben und alle anderen bleiben bzw. werden auf 0 gestellt. Daraus ergibt sich folgende Regel für die AND-Verknüpfung.....

BitA BitB (BitA&BitB)
0 0 0
0 1 0
1 0 0
1 1 1


Mit dem AND - Operator können sie außerdem prima testen ob ein Zahl gerade oder ungerade ist...

/*Download:b_and2.c*/
#include <stdio.h> int main() { int x; printf("Bitte ein Zahl eingeben : "); scanf("%d",&x); if(x&1) printf("Bit0 = 1 und daher ist die Zahl ungerade\n"); else printf("Bit0 = 0 daher eine gerade Zahl!!\n"); return 0; }

Auch sehr häufig wird dieser Operator verwendet um einzelne Bits auf 0 zu setzen. Um zum Beispiel das 3.Bit zu löschen benötigen wir nur eine Maske. Die Maske lautet für das 3.Bit...

0111 1011  

Nun können sie den Wert entweder in einen Dezimalen umrechnen (123) oder wie wir schon im Kapitel zuvor kennen gelernt haben in eine Hexzahl : 0x7B

Mit...

zahl = zahl&0x7B  

...oder...

zahl = zahl&123  

Somit hätten wir egal welchen Wert zahl hat das 3.Bit (falls gesetzt) gelöscht...(Beispiel: 128&123 oder eben 128&0x7B)

0 1 1 1 1 1 1 1
& 0 1 1 1 1 0 1 1
= 0 1 1 1 1 0 1 1


Natürlich haben sie bei den bitweise Operatoren auch folgendende Schreibweise...

zahl&=0x7B  

... die gleich zu der vorangegangenen ist.

Der Insklusive-OR-Operator |

Mit dem Inklusiv - OR-Operator | können sie im Gegensatz zum zuvor kennen gelernte AND-&-Operator bequem Bits setzen. Zuerst aber mal die Verknüpfungstabelle des OR-Operators...

BitA BitB (BitA|BitB)
0 0 0
0 1 1
1 0 1
1 1 1


Wir wollen jetzt zum Beispiel bei der Zahl 0 alle Bits bis auf Bit7 und Bit1 setzen. Zuerst benötigen wir wieder eine Maske. Benutzen sie die Hextabelle im Kapitel zuvor. Damit ist es einfacher. Also benötigen wir folgende Maske...

0111 1110   = 0x7E  oder auch 126 wenn sie wollen  

Also gehen wir wie folgt vor...

char x = 0;

x = x|0x7E; //oder auch x = x|126  

Somit sieht unsere interne Bitdarstellung folgendermaßen aus...

0 0 0 0 0 0 0 0
| 0 1 1 1 1 1 1 0
= 0 1 1 1 1 1 1 0


Natürlich hätten sie auch folgende schreibweiße benutzen können....

x|=126;  

Der Exclusiv-OR-Operator ^ (XOR)

Dieser Operator ist eine Art Ungleichheitsoperator. XOR ^ liefert nur dort eine 1 zurück wo beide Bits unterschiedlich waren....

BitA BitB (BitA^BitB)
0 0 0
0 1 1
1 0 1
1 1 0


Dieser Operator eignet sich prima dazu um Bits umzuschalten. Das heißt gesetzte Bits werden gelöscht und umgekehrt. Wenden wir unseren Operator einfach mal wahllos an...

char x=20;

x = x^55;  

...an...

0 0 0 1 0 1 0 0
^ 0 0 1 1 0 1 1 1
= 0 0 1 0 0 0 1 1


Als Ergebnis erhalten wir die Zahl 35 zurück. Auch hier können sie folgende Schreibweise benutzten...

x^=55;  

Der NOT-Operator ~

Mit dem NOT-Operator ~ (wird erzeugt mit der Tastenkombination <AltGr>+<+>) wirkt auf Zahlen so aus das er jedes Bit umdreht.....

BitA ~BitA
0 1
1 0


Bei vorzeichenbehaftete Datentypen entspricht das einer Negation plus der Subtraktion von 1....

char x=20;

x=~x;  

...dies sieht folgendermaßen aus.....

~ 0 0 0 1 0 1 0 0
= 1 1 1 0 1 0 1 1


Somit bekommen sie das Ergebnis -21 zurück.

Die Verschiebeoperatoren << und >>

Kommen wir zuerst zur Linksverschiebung << womit alle Bits um n Stellen nach links gerückt werden. Die rechts entstehenden Leerstellen werden mit 0 aufgefüllt. Achtung bei Vorzeichen! Ist der Datentype vom Typ signed ändert sich das Vorzeichen wenn eine 1 in die Bitstelle des Vorzeichens gerückt wird. Falls der linke Operand aber einen negativen Wert hat so ist das Ergebnis compilerspezifisch. Beispiel einer Linksverschiebung....

/*Download:shlft.c*/
#include <stdio.h> int main() { char x=8; printf("x=%d\n",x); x<<=1; /*Alle Bits um 1 Stelle nach links*/ printf("x=%d\n",x); return 0; }

Aus 8 wird die Zahl 16. Sehen wir uns mal an warum.....

8= 0 0 0 0 1 0 0 0
8<<=1 0 0 0 1 0 0 0 0


Hier sehen sie wie Bit3 mittels....

8<<=1;  

...um 1 Bit zu Bit4 nach links verschoben wurde. Manch einer wird es jetzt schon bemerkt haben das hier eine Multiplikation durchgeführt haben. Somit lassen sich prima die Zahlen Potenzieren. Die Bitstelle um eine Position nach links bedeutet eine Multiplikation mit 2. Um zwei Stellen nach links wir mit 4 Multipliziert, um drei mit 8, um vier mit 16 usw... Unser folgendes Beispiel errechnet nun immer die Potenz der Vorangegangenen Zahl.....

/*Download:potenz.c*/
#include <stdio.h> int main() { unsigned long cube=1; int i; printf("\nPotenzen von 2: \n"); for(i=2;i<8;i++) { printf("%d",cube); printf(" = %d\n",cube,cube<<=i); } return 0; }

Wir Potenzieren hier eine 32Bit lange Zahl vom Typ long bei der nach jeder for-Schleife das Bit um eine Stelle nach links geschoben wird. Sollte unser Schleifenzeilen die 8.Potenz auch noch ausführen so bekommen sie als Wert 0 zurück da bei der 7.Potenz der Wert bereits an der letzten Stelle gestanden hat und wenn wir Ihn um eine Stellen nach links schieben schieben wir Ihn praktisch ganz raus. In der Sprache C gibt keinen Befehl wie in Assembler RCL (Rotate trough Carry left) der bewirkt das falls das Carry-Flag des Prozessors gesetzt ist die 1 z.B. durch...

rcl eax, 1  

das Carry-Bit bei den kleinsten Bit0 wieder reinschiebt. Doch das geht hier zu weit. Welchen Vorteil hat den nun eine Multiplikation mit einer Linksverschiebung? Zum Beispiel bei Programmen bei denen es auf schnelle Berechnungen ankommt, z.B. Spiele, da die Bitverschiebung ca. 40(!) mal schneller als normale Multiplikationen sind.

Rechtsverschiebung

Die Rechtsverschiebung mit dem >>-Operator ist das Gegenstück zur Linksverschiebung << Damit könne wir nun anstatt einer Multiplikation mit 2, eine Division durch 2 erreichen. Ansonsten gilt das gleiche wie für die Linksverschiebung. Beispiel...

char x=17;

x>>=1;  Verschiebung um 1Bit nach rechts  



17= 0 0 0 1 0 0 0 1
17>>=1 0 0 0 0 1 0 0 0


Somit erhalten wir als Ergebnis die 8.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf