Cosa fa E 0XFF?

Anding un numero intero con 0xFF lascia solo il byte meno significativo. Ad esempio, per ottenere il primo byte in un short s, è possibile scrivere s & 0xFF. Questo è in genere indicato come”mascheramento”. Se byte1 è un singolo tipo di byte (come uint8_t) o è già inferiore a 256 (e di conseguenza sono tutti zeri tranne il byte meno significativo) non è necessario mascherare i bit più alti, poiché sono già zero.

Vedi la risposta di tristopiaPatrick Schlüter qui sotto quando potresti lavorare con tipi firmati. Quando si eseguono operazioni bit a bit, si consiglia di lavorare solo con tipi senza segno.

se byte1 è un tipo intero a 8 bit, allora è inutile – se è più di 8 bit, ti darà essenzialmente gli ultimi 8 bit del valore:

 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 & 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ------------------------------- 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1

Il pericolo della seconda espressione viene se il tipo di byte1 è char. In tal caso, alcune implementazioni possono avere signed char, che si tradurrà in estensione del segno durante la valutazione.

signed char byte1 = 0x80;signed char byte2 = 0x10;unsigned short value1 = ((byte2 << 8) | (byte1 & 0xFF));unsigned short value2 = ((byte2 << 8) | byte1);printf("value1=%hu %hx\n", value1, value1);printf("value2=%hu %hx\n", value2, value2);

stamperà

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

L’ho provato su gcc v3.4.6 su Solaris SPARC 64 bit e il risultato è lo stesso con byte1 e byte2 dichiarato come char.

TL;DR

Il mascheramento è quello di evitare l’estensione implicita del segno.

MODIFICA: ho controllato, è lo stesso comportamento in C++.

EDIT2: Come richiesto spiegazione dell’estensione del segno.L’estensione del segno è una conseguenza del modo in cui C valuta le espressioni. C’è una regola in C chiamata regola di promozione. C trasmetterà implicitamente tutti i piccoli tipi a int prima di eseguire la valutazione. Vediamo cosa succede alla nostra espressione:

unsigned short value2 = ((byte2 << 8) | byte1);

byte1 è una variabile contenente bit pattern 0xFF. Se char è unsigned quel valore viene interpretato come 255, se è signed è -128. Quando si esegue il calcolo, C estenderà il valore a una dimensione int (16 o 32 bit in generale). Ciò significa che se la variabile è unsigned e manterremo il valore 255, il modello di bit di quel valore come int sarà 0x000000FF. Se è signed vogliamo il valore -128 quale modello di bit è 0xFFFFFFFF. Il segno è stato esteso alla dimensione del tempo utilizzato per fare il calcolo.E quindi oring il temporaneo produrrà il risultato sbagliato.

Sull’assemblaggio x86 viene eseguito con l’istruzione movsx (movzx per l’estensione zero). Altre CPU avevano altre istruzioni per questo (6809 aveva SEX).

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.