Was ist Bitmaskierung?

191

Ich bin ziemlich neu in der C-Programmierung und habe auf Bitmaskierung gestoßen. Kann mir jemand das allgemeine Konzept und die Funktion der Bitmaskierung erklären? Beispiele werden sehr geschätzt.

Mr.Z.
quelle
1
Verstehen Sie bitweise Operatoren wie & | ^ etc und Boolesche Logik im Allgemeinen? Jede Erklärung von Maskenoperationen erfordert dies.
Paul R
1
Ja, ich verstehe bitweise Operatoren und boolesche Logik
Mr.Z
2
Ich weiß, dass Links nicht gepostet werden sollten, aber die Wikipedia-Erklärung ist großartig: en.wikipedia.org/wiki/Mask_(computing)
pevik
2
@pevik Es ist in Ordnung, einen Link zu posten, aber mit einer Beschreibung, damit der Post seinen Zweck der Beantwortung erfüllen kann, wenn der Link eines Tages stirbt. Auch Link sollte nicht nur zu Werbezwecken sein.
Dexter

Antworten:

243

Eine Maske definiert, welche Bits Sie behalten möchten und welche Bits Sie löschen möchten.

Beim Maskieren wird eine Maske auf einen Wert angewendet. Dies wird erreicht durch:

  • Bitweises UND-Verknüpfung, um eine Teilmenge der Bits im Wert zu extrahieren
  • Bitweises ODER-Ordnen, um eine Teilmenge der Bits im Wert festzulegen
  • Bitweises XORing, um eine Teilmenge der Bits im Wert umzuschalten

Unten finden Sie ein Beispiel für das Extrahieren einer Teilmenge der Bits im Wert:

Mask:   00001111b
Value:  01010101b

Das Anwenden der Maske auf den Wert bedeutet, dass wir die ersten (höheren) 4 Bits löschen und die letzten (niedrigeren) 4 Bits behalten möchten. Somit haben wir die unteren 4 Bits extrahiert. Das Ergebnis ist:

Mask:   00001111b
Value:  01010101b
Result: 00000101b

Die Maskierung wird mit AND implementiert, daher erhalten wir in C:

uint8_t stuff(...) {
  uint8_t mask = 0x0f;   // 00001111b
  uint8_t value = 0x55;  // 01010101b
  return mask & value;
}

Hier ist ein ziemlich häufiger Anwendungsfall: Extrahieren einzelner Bytes aus einem größeren Wort. Wir definieren die höherwertigen Bits im Wort als das erste Byte. Wir verwenden dafür zwei Operatoren &und >>(nach rechts verschieben). So können wir die vier Bytes aus einer 32-Bit-Ganzzahl extrahieren:

void more_stuff(uint32_t value) {             // Example value: 0x01020304
    uint32_t byte1 = (value >> 24);           // 0x01020304 >> 24 is 0x01 so
                                              // no masking is necessary
    uint32_t byte2 = (value >> 16) & 0xff;    // 0x01020304 >> 16 is 0x0102 so
                                              // we must mask to get 0x02
    uint32_t byte3 = (value >> 8)  & 0xff;    // 0x01020304 >> 8 is 0x010203 so
                                              // we must mask to get 0x03
    uint32_t byte4 = value & 0xff;            // here we only mask, no shifting
                                              // is necessary
    ...
}

Beachten Sie, dass Sie die Reihenfolge der obigen Operatoren ändern können, zuerst die Maske und dann die Verschiebung. Die Ergebnisse sind die gleichen, aber jetzt müssten Sie eine andere Maske verwenden:

uint32_t byte3 = (value & 0xff00) >> 8;
user239558
quelle
5
Gute Antwort, aber Maskierung kann auch angewendet werden, um bestimmte Bits mit ODER- oder XOR-Operationen und einer geeigneten Maske zu setzen oder umzuschalten .
Paul R
@ user239558 danke für das Beispiel und die richtige Syntax. @ Paul R. Würde ich einfach Maske UND Wert in dem Beispiel von user239558
Mr.Z
@ Mr.Z: In C, C ++ und verwandten Sprachen würden Sie den bitweisen AND- Operator verwenden, der als geschrieben ist &.
Paul R
@ Mr.Z Zum Beispiel: Löschen Sie ein Byte eines uint32_t, indem Sie den Inhalt weg maskieren : #define MASK 0x000000FF .... my_uint32_t &= ~MASK.
Lundin
Das bum anzuzeigende binäre Literal wird nicht von allen Compilern unterstützt, richtig?
Ungeheuer
76

Maskieren bedeutet, einen gewünschten Teil der Informationen beizubehalten , zu ändern oder zu entfernen. Sehen wir uns eine Bildmaskierungsoperation an. wie - diese Maskierungsoperation entfernt alles, was nicht Haut ist-

Geben Sie hier die Bildbeschreibung ein

In diesem Beispiel führen wir eine UND- Operation durch. Es gibt auch andere Maskierungsoperatoren - OR , XOR .


Bitmaskierung bedeutet das Auferlegen einer Maske über Bits. Hier ist eine Bitmaskierung mit UND -

     1 1 1 0 1 1 0 1   [input]
(&)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     0 0 1 0 1 1 0 0  [output]

Es 1bleiben also nur die mittleren 4 Bits (da sich diese Bits in dieser Maske befinden) übrig.

Sehen wir uns das mit XOR an -

     1 1 1 0 1 1 0 1   [input]
(^)  0 0 1 1 1 1 0 0    [mask]
------------------------------
     1 1 0 1 0 0 0 1  [output]

Jetzt werden die mittleren 4 Bits umgedreht ( 1wurden 0, 0wurden 1).


Mit der Bitmaske können wir also auf einzelne Bits zugreifen [ Beispiele ]. Manchmal kann diese Technik auch zur Verbesserung der Leistung verwendet werden. Nehmen Sie dies zum Beispiel-

bool isOdd(int i) {
    return i%2;
}

Diese Funktion gibt an, ob eine Ganzzahl ungerade / gerade ist. Mit Bitmasken können wir das gleiche Ergebnis mit mehr Effizienz erzielen.

bool isOdd(int i) {
    return i&1;
}

Kurze Erklärung : Wenn das niedrigstwertige Bit einer Binärzahl 1ungerade ist, ist es ungerade. denn 0es wird eben sein. Also, indem Sie und mit 1wir alle anderen Bits mit Ausnahme der niedrigstwertigen Bit , dh zu entferne:

     55  ->  0 0 1 1 0 1 1 1   [input]
(&)   1  ->  0 0 0 0 0 0 0 1    [mask]
---------------------------------------
      1  <-  0 0 0 0 0 0 0 1  [output]
Minhas Kamal
quelle
1
Um eine ganze Zahl in eine ungerade Zahl umzuwandeln. wenn es eine gerade Zahl ist: i = i | 1. Dies ist praktisch, wenn wir versuchen, eine Sequenz wie 1, 3, 5, ..., 2, 4, 6, ... zu
generieren
Sie können auch die folgende Operation verwenden, um die Zahl mit nur dem niedrigstwertigen Bit aus einer Ganzzahl zu finden: lsb = i & -i
Harshit Sharma