![]()  | 
            ![]()  | 
        |
    
 
 Mit dem bitweisen UND-Operator lässt sich sehr gut testen, ob eine Zahl gerade oder ungerade ist. Es muss nur Bit 0 (bzw. das 1. Bit) daraufhin überprüft werden, ob es gesetzt (ungerade, also = 1) oder nicht gesetzt (gerade, also = 0) ist. Folgendes Beispiel demonstriert dies: /* gerade.c */
#include <stdio.h>
int main(void) {
   int x;
   printf("Bitte geben Sie eine Zahl ein: ");
   scanf("%d",&x);
   if(x&1)  // Ist das erste Bit gesetzt?
      printf("Eine ungerade Zahl\n");
   else     // Nein, es ist nicht gesetzt
      printf("Eine gerade Zahl\n");
   return 0;
}
8.5.2 Bitweises ODER 
      
 | 
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BitA | BitB | (BitA|BitB) | 
| 0 | 0 | 0 | 
| 0 | 1 | 1 | 
| 1 | 0 | 1 | 
| 1 | 1 | 1 | 
Dieser exklusive ODER-Operator liefert nur dann eine 1 zurück, wenn beide Bits unterschiedlich sind. Er ist sehr gut geeignet, um Bits umzuschalten. Alle gesetzten Bits werden gelöscht und alle gelöschten gesetzt. Beispielsweise:
char x=20; x = x^55; // x=35
In binärer Darstellung ergibt sich aus dieser Operation folgendes Bild:

Hier klicken, um das Bild zu Vergrößern
Abbildung 8.5 Verwendung des exklusiven ODER-Operators
Für XOR-Verknüpfungen gilt folgende Verknüpfungstabelle:
| BitA | BitB | BitA^BitB | 
| 0 | 0 | 0 | 
| 0 | 1 | 1 | 
| 1 | 0 | 1 | 
| 1 | 1 | 0 | 
Der NOT-Operator (~) wirkt sich auf Zahlen so aus, dass er jedes einzelne Bit invertiert. Bei vorzeichenbehafteten Datentypen entspricht das einer Negation mit anschließender Subtraktion von 1:
char x=20; x=~x; /* x= –21 */
Für den NOT-Operator gilt folgende Verknüpfungstabelle:
| BitA | ~BitA | 
| 0 | 1 | 
| 1 | 0 | 
Mit einer Linksverschiebung (<<) werden alle Bits einer Zahl um n Stellen nach links gerückt. Die rechts entstehenden Leerstellen werden mit 0 aufgefüllt.
| 
 Achtung Achtung bei Vorzeichen! Ist der Datentyp 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 Compiler-spezifisch.  | 
Beispiel einer Linksverschiebung:
/* shift_left.c */
#include <stdio.h>
int main(void) {
   char x=8;
   printf("x=%d\n",x);
   x<<=1;        // Alle Bits um 1 Stelle nach links
   printf("x=%d\n",x);
   return 0;
}
Warum aus dem Wert 8 eine 16 wurde, wird aus der folgenden Bitdarstellung ersichtlich:

Hier klicken, um das Bild zu Vergrößern
Abbildung 8.6 Bitverschiebung nach links
Sie werden es bemerkt haben, hier wurde eine Multiplikation durchgeführt. Auf diese Weise können Zahlen sehr gut potenziert werden. Die Bitstelle um eine Position nach links zu rücken, bedeutet mathematisch eine Multiplikation mit 2. Bei Einrückung um zwei Stellen nach links wird mit 4 multipliziert, bei drei mit 8, bei vier mit 16 usw.
Solche Bitverschiebungen können – abhängig vom System – bis zu 40(!)-mal schneller ablaufen als normale arithmetische Berechnungen im Stil von 4*x.
Die Rechtsverschiebung mit dem >>-Operator ist das Gegenstück zur Linksverschiebung (<<). Damit können Sie statt einer Multiplikation mit 2 eine Division durch 2 bewirken. Ansonsten gilt das Gleiche wie für die Linksverschiebung.
Oft ist eine Funktion wünschenswert, mit der eine Zahl daraufhin getestet wird, ob ein bestimmtes Bit gesetzt ist, oder mit der sich gezielt einzelne Bits setzen oder löschen lassen. Hierzu ein Listing mit entsprechenden Funktionen:
/* playing_bits.c */
#include <stdio.h>
#define BYTE unsigned char
/* Funktion : Bit_Test()
 * val  : der Wert, den es zu testen gilt
 * bit  : Bitnummer, die abgefragt wird, ob gesetzt (0–7)
 * Rückgabewert :  (1)=Bit gesetzt; (0)=Bit nicht gesetzt
 */
int Bit_Test(BYTE val, BYTE bit) {
   BYTE test_val = 0x01;    /* dezimal 1 / binär 0000 0001 */
   /* Bit an entsprechende Pos. schieben */
   test_val = (test_val << bit);
   /* 0=Bit nicht gesetzt; 1=Bit gesetzt */
   if ((val & test_val) == 0)
      return 0;      /* Nicht gesetzt */
   else
      return 1;      /* gesetzt */
}
/* Funktion :  Bit_Set()
 * val  : Wert, bei dem Bit gesetzt werden soll
 * bit  : Bitnummer, die gesetzt werden soll (0–7)
 * Rückgabewert : keiner
 */
void Bit_Set(BYTE *val, BYTE bit) {
   BYTE test_val = 0x01;      /* dezimal 1 / binär 0000 0001 */
   /* Bit an entsprechende Pos. schieben */
   test_val = (test_val << bit);
   *val = (*val | test_val);     /* Bit an Pos bit setzen */
}
/* Funktion : Bit_Clear()
 * val  : Wert, bei dem Bit gelöscht werden soll
 * bit  : Bitnummer, die gelöscht werden soll (0–7)
 * Rückgabewert :  keiner
 */
void Bit_Clear(BYTE *val, BYTE bit) {
   BYTE test_val = 0x01;        /* dezimal 1 / binär 0000 0001 */
   /* Bit an entsprechende Pos. schieben */
   test_val = (test_val << bit);
   *val = (*val & (~test_val));   /* Bit an Pos bit löschen*/
}
int main(void) {
   BYTE wert = 0;
   /* Test, ob Bit 0 gesetzt */
   printf("%s\n",Bit_Test(wert, 0)?"gesetzt":"nicht gesetzt");
   Bit_Set(&wert, 0);    /* Bit 0 setzen */
   /* Wieder testen, ob Bit 0 gesetzt */
   printf("%s\n",Bit_Test(wert, 0)?"gesetzt":"nicht gesetzt");
   Bit_Clear(&wert, 0);  /* Bit 0 wieder löschen */
   /* Wieder testen ob Bit 0 gesetzt */
   printf("%s\n",Bit_Test(wert, 0)?"gesetzt":"nicht gesetzt");
   return 0;
}
Die Funktionen können natürlich den eigenen Bedürfnissen entsprechend angepasst werden und dienen nur als Anregung für weitere Spielereien mit Bits und Bytes.
| << zurück | 
                
  | 
        ||||||||||||||
                
  | 
        ||||||||||||||
                
  | 
        ||||||||||||||
                
  | 
        ||||||||||||||
Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.