Bitfeld

aus Wikipedia, der freien Enzyklopädie
(Weitergeleitet von Bitmaske)
Wechseln zu: Navigation, Suche

In der Informationstechnik und Programmierung bezeichnet ein Bitfeld eine Binärzahl, in der einzelne Bits oder Gruppen von Bits mit unterschiedlichen Bedeutungen zusammengefasst wurden. Es stellt eine Art Verbunddatentyp auf Bit-Ebene dar. Im Gegensatz dazu stehen primitive Datentypen, bei denen alle Stellen gemeinsam als ein Wert interpretiert wird.

Eine verbreitete Verwendung ist die bei der jede einzelne Stelle der Binärzahl ein Flags repräsentiert. Dabei entspricht jede Stellen praktisch einer booleschen Variable. Daneben können aber auch mehrere Stellen einen Wert bilden, z. B. können in einem Byte auch zwei Nibbles zusammengefasst sein oder, wie bei IPv4-Adressen, in einem 32-Bit-Datenwort in 24 Bit Netzwerk- und 8 Bit Hostteil.

Verwendung[Bearbeiten]

Bitfelder werden typischerweise bei der hardwarenahen oder der Systemprogrammierung eingesetzt. Hier dienen sie meist dazu, bei Peripheriegeräten ein bestimmtes Verhalten einzustellen. Das liegt daran, dass bspw. das Aktivieren einer bestimmten Funktionalität in Hardware leicht über das Setzen einer einzigen Datenleitung, einem Bit, signalisiert werden kann. Um einfacher mit der Software oder anderen Geräten zu kommunizieren oder weil bspw. I/O-Ports nur in begrenzter Menge vorhanden sind, werden mehrere solcher Leitungen dann zu einem Datenwort zusammengefasst, dem Bitfeld.

Daneben werden Bitfelder aber auch bei der Anwendungsprogrammierung verwendet, wo eine Vielzahl an Parametern übergeben werden soll. Hier kann die Lesbarkeit des Quellcodes verbessert werden, wenn statt einer langen Parameterliste, bei der jeder Parameter explizit angegeben werden muss, nur ein Bitfeld mit den gewünschten Flags zusammengestellt wird.

Bitfelder zu Verwenden um Speicherplatz einzusparen macht in der Anwendungsprogrammierung heutzutage keinen Sinn, außer in seltenen Fällen, wie z. B. bei eingebetteten Systemen, wenn Speicher eine extrem begrenzte Ressource ist. Es wird für boolesche Variablen meist ein ganzes Byte oder sogar mehrere verwendet, da Speicher hier in mehr als ausreichender Menge vorhanden ist. Auch ist der Zugriff auf einzelne Bits eines Datenworts oft ineffizienter, als auf das gesamte Datenwort und ist meist auch nicht parallelisierbar.

Beispiel in OpenGL[Bearbeiten]

In OpenGL wird bspw. die Funktion glClear definiert, welche einen oder mehrere von vier Grafikpuffern löscht. Die Entwickler hätten nun vier Parameter definieren können, welche jeweils angeben ob der Grafikpuffer gelöscht werden soll oder nicht. Der Funktionsaufruf würde folgendermaßen aussehen:

 void glClear(1, 1, 0, 0);

Dies ist aber weder effizient, da vier Variablen übergeben werden müssen, noch sehr leserlich. Daher wurde in der gl.h für jeden Puffer ein sogenanntes benanntes Flag definiert:

 #define GL_DEPTH_BUFFER_BIT               0x00000100
 #define GL_ACCUM_BUFFER_BIT               0x00000200
 #define GL_STENCIL_BUFFER_BIT             0x00000400
 #define GL_COLOR_BUFFER_BIT               0x00004000

Und für die Funktion wurde nur ein einzelner Parameter definiert:

 void glClear(GLbitfield mask); // GLbitfield ist ein typedef auf unsigned int

Der Funktionsaufruf sieht nun folgendermaßen aus:

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Verwendung in C und C#[Bearbeiten]

In der Programmiersprache C ist es zudem möglich, Bitfelder zu verwenden, die den direkten Zugriff auf einzelne Bits erlauben. Es ist jedoch zu beachten, dass der Code dadurch prozessorabhängig wird, da die Byte-Reihenfolge von der Prozessorarchitektur beeinflusst wird.

 struct struct-type-name {
     type [name1] : length;
     type [name2] : length;
     //...
     type [nameN] : length;
 } variable-list;

In der Programmiersprache C# ist es mittels der Flags Attribute möglich, eine Enumeration als Bitfeld zu deklarieren.[1] Außerdem stellt das .NET Framework die Datenstruktur BitArray zur Verfügung, welche einzelne Bits kompakt speichert und boolesche Operationen ermöglicht.

Bitmasken[Bearbeiten]

Als Bitmasken werden Bitfelder bezeichnet, deren Stellen selbst keine Information repräsentieren, sondern die dazu verwendet werden, um Bitfelder auszulesen oder zu manipulieren.

Ein in der Netzwerktechnik verbreitetes Beispiel für eine Bitmaske ist die Netzmaske. Sie bestimmt welche der führenden Bits einer IP-Adresse das Netzpräfix sind, d. h. welcher Adressbereich als internes und welcher als externes Netz beim Routen betrachtet wird.

Bit auslesen[Bearbeiten]

Um ein oder mehrere Bits aus einem Bitfeld auszulesen wird es mit einer Bitmaske über die bitweise Und-Operation verknüpft. In der Bitmaske stehen an allen Stellen, die nicht betrachtet werden sollen eine „0“. Diese Stellen werden durch die UND-Verknüpfung ausgeblendet, d. h. auf Null gesetzt. Die Stellen, die betrachtet oder ausgelesen werden sollen enthalten eine „1“ in der Bitmaske und werden daher unverändert aus dem Bitfeld ins Ergebnis übernommen.

Beispiel

1-Bit:

    01001011 Bitfeld
AND 00001000 Bitmaske
-------------
=   00001000 Ergebnis

0-Bit:

    01001011 Bitfeld
AND 00000100 Bitmaske
-------------
=   00000000 Ergebnis

Das Ergebnis ist Null, wenn die Stellen der Bitmaske im Bitfeld ebenfalls Null sind. Ist mindestens eines davon auf „1“ gesetzt, sind die entsprechenden Bits auch im Ergebnis „1“, d. h. das Ergebnis ist ungleich Null.

Da Werte von Null in den meisten Programmiersprachen zu einem logischen false und Werte ungleich Null zu einem logisch true ausgewertet werden, kann nun das Ergebnis leicht mit einer bedingten Verzweigung daraufhin überprüft werden, ob eines der Bits der Bitmaske im Feld gesetzt war:

if (Ergebnis)
   // Bit gesetzt
else
   // Bit nicht gesetzt

Bits setzen[Bearbeiten]

Sollen Bits im Bitfeld einen bestimmten Wert annehmen, müssen die entsprechenden Stellen im Bitfeld auf „1“ und alle anderen auf „0“ gesetzt werden. Um die Stellen auf „1“ zu setzen, muss das Bitfeld mit der Bitmaske addiert oder über ein bitweises Oder verknüpft werden. Umgekehrt erhält man an den gewünschten Stellen eine „0“ wenn man Feld und Maske über ein NAND verknüpft, also zuerst die Maske invertiert und sie dann über eine Und-Operation mit dem Feld verknüpft.

Beispiel

Setzen von Bits auf „1“:

    01001011 Bitfeld
OR  00000100 Bitmaske
-------------
=   01001111 Ergebnis

Setzen von Bits auf „0“:

NOT 00001000 Bitmaske
-------------
=   11110111 invertierte Bitmaske
AND 01001011 Bitfeld
-------------
=   01000011 Ergebnis

Bits umschalten[Bearbeiten]

Sollen einzelne Bits umgeschaltet (englisch to toggle) bzw. invertiert werden, setzt man die entsprechenden Stellen in der Bitmaske auf „1“ und alle anderen auf „0“ und verknüpft Bitfeld und Bitmaske über ein exklusives Oder.

    01001011 Information
XOR 00000110 Bitmaske
-------------
=   01001101 Ergebnis

Bitmasken zusammenfassen[Bearbeiten]

Bitmasken können zusammengefasst werden, z. B. um in einer Operation mehrere Bits auf einmal zu überprüfen oder zu setzen. Dazu addiert man lediglich die einzelnen Bitmasken oder verknüpft sie über ein bitweises Oder.

    00000001 Bitmaske1
OR  00000010 Bitmaske2
-------------
    00000011 zusammengefasste Bitmaske

Einzelnachweise[Bearbeiten]

  1. http://msdn.microsoft.com/de-de/library/system.flagsattribute.aspx