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.