Cos'è il Bit Masking?


191

Sono abbastanza nuovo nella programmazione in C e ho riscontrato un po 'di mascheramento. Qualcuno può spiegarmi il concetto generale e la funzione del bit masking? Gli esempi sono molto apprezzati.


1
Capisci operatori bit a bit come & | ^ etc e logica booleana in generale? Qualsiasi spiegazione delle operazioni della maschera richiederà questo.
Paul R,

1
Sì, ho una comprensione degli operatori bit a bit e della logica booleana
Mr.Z

2
So che i link non dovrebbero essere pubblicati, ma la spiegazione di Wikipedia è fantastica: en.wikipedia.org/wiki/Mask_(computing)
pevik

2
@pevik è ok per pubblicare un link ma con qualche descrizione in modo che se un link si interrompe un giorno, il post è ancora in grado di servire al suo scopo di rispondere. anche il link non dovrebbe essere per meri scopi promozionali.
Dexter,

Risposte:


246

Una maschera definisce quali bit si desidera conservare e quali bit si desidera cancellare.

Il mascheramento è l'atto di applicare una maschera a un valore. Questo si ottiene facendo:

  • AND bit a bit per estrarre un sottoinsieme dei bit nel valore
  • OR bit a bit per impostare un sottoinsieme dei bit nel valore
  • BitOR XORing per attivare / disattivare un sottoinsieme dei bit nel valore

Di seguito è riportato un esempio di estrazione di un sottoinsieme dei bit nel valore:

Mask:   00001111b
Value:  01010101b

Applicare la maschera al valore significa che vogliamo cancellare i primi 4 (più alti) 4 bit e mantenere gli ultimi (inferiori) 4 bit. Quindi abbiamo estratto i 4 bit inferiori. Il risultato è:

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

Il mascheramento è implementato usando AND, quindi in C otteniamo:

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

Ecco un caso d'uso abbastanza comune: Estrarre singoli byte da una parola più grande. Definiamo i bit di ordine superiore nella parola come primo byte. Per questo utilizziamo due operatori &, e >>(sposta a destra). Ecco come possiamo estrarre i quattro byte da un numero intero a 32 bit:

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
    ...
}

Nota che potresti cambiare l'ordine degli operatori sopra, puoi prima fare la maschera, poi il turno. I risultati sono gli stessi, ma ora dovresti usare una maschera diversa:

uint32_t byte3 = (value & 0xff00) >> 8;

5
Buona risposta ma il mascheramento può anche essere applicato per impostare o attivare specifici bit con operazioni OR o XOR e una maschera adatta.
Paul R,

@ user239558 grazie per l'esempio e la sintassi corretta. @ Paul R. Direi semplicemente maschera E valore nell'esempio fornito da user239558
Mr.Z

@ Mr.Z: in C, C ++ e nelle lingue correlate faresti l' operatore AND bit a bit , che è scritto come &.
Paul R,

@ Mr.Z Ad esempio: chiaro un byte di un uint32_t mascherando il contenuto te: #define MASK 0x000000FF .... my_uint32_t &= ~MASK.
Lundin,

il bper indicare il letterale binario non è supportato da tutti i compilatori, giusto?
Ungeheuer,

76

Mascherare significa conservare / modificare / rimuovere una parte desiderata di informazioni. Consente di vedere un'operazione di mascheramento delle immagini; come- questa operazione di mascheramento sta rimuovendo qualsiasi cosa che non sia pelle-

inserisci qui la descrizione dell'immagine

In questo esempio stiamo eseguendo un'operazione AND . Esistono anche altri operatori di mascheramento: OR , XOR .


Bit-Masking significa imporre la maschera sui bit. Ecco un po 'mascheramento con AND -

     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]

Quindi, 1rimangono solo i 4 bit centrali (poiché questi bit sono in questa maschera).

Vediamo questo con XOR -

     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]

Ora, i 4 bit centrali vengono capovolti (sono 1diventati 0, sono 0diventati 1).


Quindi, usando la maschera di bit possiamo accedere ai singoli bit [ esempi ]. A volte, questa tecnica può essere utilizzata anche per migliorare le prestazioni. Prendi questo per esempio-

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

Questa funzione indica se un numero intero è pari / dispari. Possiamo ottenere lo stesso risultato con maggiore efficienza utilizzando la maschera di bit-

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

Breve spiegazione : se il bit meno significativo di un numero binario è 1allora è dispari; per 0lo sarà ancora. Quindi, facendo AND con 1stiamo rimuovendo tutti gli altri bit tranne il bit meno significativo, ovvero:

     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]

1
Inoltre, per convertire un numero intero in un numero dispari. se è un numero pari: i = i | 1. Questo è utile quando stiamo cercando di generare una sequenza come 1, 3, 5, ..., 2, 4, 6, ...
Harshit Sharma

Puoi anche usare la seguente operazione per trovare il numero con solo il bit meno significativo di un numero intero: lsb = i & -i
Harshit Sharma
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.