ELEMANIA
PIC16F690 - Operatori bit a bit
Operatori sui bit

Per una trattazione generale degli operatori aritmetici e degli operatori logici del linguaggio C, rimandiamo il lettore alle apposite sezioni di Programmiamo. Qui invece ci occuperemo nello specifico degli operatori bit a bit (bitwise operators), cioè di quelle operazioni che agiscono sui singoli bit di una variabile.

La tabella seguente riassume gli operatori bit a bit del linguaggio C:

Simbolo Operatore
& AND bit a bit
| OR bit a bit
^ EXOR bit a bit
<< shift a sinistra
>> shift a destra
~ NOT bit a bit (complemento a 1)

Vediamo rapidamente il loro funzionamento.

Bitwise AND, OR, EXOR, NOT

Per una spiegazione generale sul significato degli operatori logici, si rimanda il lettore alle lezioni sull'algebra di Boole. Vediamo ora come funziona l'operatore & (AND bit a bit). Esso esegue l'AND logico bit a bit fra due valori binari. Esempio:

unsigned char a, b, c;
a = 0b01011001 ;
b = 0b00001111 ;
c = a & b;

Nell'esempio sono state usate variabili unsigned char a 8 bit, ma l'operatore funziona con variabili di qualsiasi dimensione (purché intere). Al termine delle precedenti istruzioni la variabile c vale 0b00001001, cioè il risultato dell'operazione logica AND eseguita su ogni coppia di bit di a e di b. La seguente figura dovrebbe chiarire il funzionamento dell'operatore:

bitwise AND

Si osservi che la metà superiore (nibble) di a viene annullata dall'AND con b, mentre i 4 bit inferiori di a vengono ricopiati uguali in c. Si dice anche che b fa da maschera (mask) a.

Si presti infine attenzione a non confondere l'operatore bitwise & con l'operatore logico && (usato nelle condizioni degli if, while etc.).

In modo perfettamente analogo all'AND funzionano anche gli operatori OR (|) e EXOR (^). L'operatore NOT (~, simbolo tilde, ALT+126 su tastiera Windows) è leggermente diverso in quanto si tratta di un operatore unario, cioè con un solo operando. La sua funzione è quella di invertire tutti i bit dell'operando, trasformando 0 in 1 e viceversa. Esempio:

unsigned char a, b;
a = 0b01011001 ;
b = ~a;

Alla fine delle precedenti operazioni a vale 0b10100110. Questo tipo di operazione si chiama anche complemento a uno. L'operazione di complemento a due, che consente di rappresentare un numero negativo in binario, si effettua semplicemente con l'operatore '-'. Esempio:

unsigned char a, b;
a = 0b01011001 ;
b = -a;  // b contiene il complemento a due di a

 

Operatori di shift

L'operatore << trasla verso sinistra tutti i bit di un numero del numero di posizioni specificate, aggiungendo zeri nei bit meno significativi. Esempio:

unsigned char a, b;
a = 0b01011001 ;
b = a<<1;

In questo caso a viene traslato verso sinistra di una posizione e dunque b vale 0b10110010. Ovviamente è possibile effettuare traslazioni di più di una posizione. Inoltre in generale il numero di traslazioni può essere specificato anche per mezzo di un'altra variabile o di un'espressione. Esempi:

unsigned char a, b, c;
a = 0b01011001 ;
c = 3;
b = a<<c;

In questo caso a viene traslato verso sinistra di tante posizioni quante è indicato dalla variabile c (in questo caso 3 posizioni).

Osserviamo che ogni traslazione verso sinistra di un numero binario equivale a moltiplicarlo per 2. Per esempio:

x << 1     equivale a     x = x * 2
x << 2     equivale a     x = x * 4
x << 3     equivale a     x = x * 8
....

In modo analogo funziona l'operatore >> (shift verso destra) che equivale ad eseguire una serie di divisioni (intere) per due.

Non esistono operatori in C per effettuare la rotazione binaria, cioè un'operazione che, oltre a traslare, riporti il bit in uscita in ingresso dall'altra parte. Tuttavia una rotazione verso sinistra di un bit può essere eseguita nel modo indicato nell'esempio seguente:

unsigned char a, b;
a = 0b11011001 ;
b = (a << 1) | (a >> 7);

Alla fine b contiene il valore 0b10110011. In modo analogo la rotazione verso sinistra di due posizioni si può eseguire così:

unsigned char a, b;
a = 0b11011001 ;
b = (a << 2) | (a >> 6);

In modo simile la rotazione verso destra di una posizione si esegue nel seguente modo:

unsigned char a, b;
a = 0b11011001 ;
b = (a >> 1) | (a >> 7);

Alla fine delle precedenti istruzioni b vale 0b11101100.

 

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it