The C++ Compass
|
>FAQ<
|
Home Risorse Utilities Compilatori GUI Toolkits Libri Download FAQ Who am I |
Come estrarre un singolo bit da un dato "più grande" ?
Vi sono vari modi, ma il più semplice e tipico è quello di usare l'operatore & (singola ampersand, da leggersi come "AND bit-per-bit" o giù di lì) da applicare mediante una maschera di bit.
Per leggere , ad esempio, il primo bit da un tipo di dato a 32 bit la maschera può essere scritta in vari modi: const unsigned int transition_mask = 0x80000000; oppure const unsigned int transition_mask = 1 << 31; In un tipo di dato a 32 bit qual'è il bit più significativo, il numero 0 o il numero 31 ? Ogni produttore di chip usa la sua notazione (diversi produttori dello stesso chip a volte usano notazioni diverse fra loro!); Intele Microsoft di solito sono coerenti nel chiamare 0 il meno significativo e così via, così che, se X e` il "numero di bit", 1<<X e` la maschera (decisamente più comodo rispetto alla convenzione contraria). Per Intel (e MS), la convenzione è coerentemente "little-endian": i bit, byte, ecc, meno significativi, sono sempre quelli identificati da indirizzi, numeri, ecc, numericamente più bassi (beh, al 99+%, almeno -- il 100% non e` di questo mondo! --). Lo stesso risultato si può ottenere con l'operatore di shift binario a destra >> (o a sinistra <<) ? Sì, ma attenzione: >> su di un numero CON SEGNO può "propagare" il bit di segno, cioè, se int è 32 bit: int pippo = 0x80000000; pippo>>31; // può essere 0xFFFFFFFF unsigned int upippo = 0x80000000; upippo>>31; // sicuramente vale 1 meglio quindi, per sapere con certezza cosa succede, applicare lo shift solo a interi SENZA segno. Comunque, (pippo>>31)&1 dovrebbe essere nuovamente il bit cercato (spostato nella posizione meno significativa), cioè valere 0 o 1. C'è un MINIMO di overhead (una istruzione di macchina) in questo approccio: la maschera col bit 31 settato è preparata a compile-time (zero costo runtime) quindi l'unica operazione di macchina è lo AND, mentre questo shift è da farsi a runtime (e uno shift di 31 bit potrebbe prendere molteplici tempi di clock, a seconda di quale sia esattamente la CPU che si sta utilizzando, anche se è espresso come una singola istruzione di macchina). 99+% del tempo questo non ha importanza, ma nel dubbio è meglio prendere l'abitudine di non fare delle elaborazioni "inutili"; cioè, se si deve testare dei bit di una parola, e si sa a priori di che bit si tratta, è meglio farlo con un AND con una maschera costante, piuttosto che con shift E and. Un altro approccio consiste nell'uso dei "bit-field", ma non lo consiglio -- è meno portabile e quindi più oscuro, per quanto, a prima vista, possa invece sembrare più leggibile. Comunque, questione di gusti e di stile personale. |
webmaster@thecppcompass.org |