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.
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.
Risposte:
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:
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;
&
.
#define MASK 0x000000FF .... my_uint32_t &= ~MASK
.
b
per indicare il letterale binario non è supportato da tutti i compilatori, giusto?
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-
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, 1
rimangono 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 1
diventati 0
, sono 0
diventati 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 è 1
allora è dispari; per 0
lo sarà ancora. Quindi, facendo AND con 1
stiamo 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]