ce face și 0xFF face?

și un număr întreg cu 0xFF lasă doar octetul cel mai puțin semnificativ. De exemplu, pentru a obține primul octet într-un short s, puteți scrie s & 0xFF. Acest lucru este de obicei denumit „mascare”. Dacă byte1 este fie un singur tip de octet (cum ar fi uint8_t), fie este deja mai mic de 256 (și ca rezultat sunt toate zerourile, cu excepția octetului cel mai puțin semnificativ), nu este nevoie să mascați biții mai mari, deoarece sunt deja zero.

a se vedea tristopiaPatrick Schl răspunsul de mai jos, atunci când s-ar putea fi de lucru cu tipuri semnate. Când efectuați operații pe biți, vă recomand să lucrați numai cu tipuri nesemnate.

dacă byte1 este un tip întreg pe 8 biți, atunci este inutil – dacă este mai mult de 8 biți, vă va oferi în esență ultimii 8 biți ai valorii:

 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

pericolul celei de-a doua expresii vine dacă tipul de byte1 este char. În acest caz, unele implementări îl pot avea signed char, ceea ce va duce la extinderea semnului la evaluare.

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);

va imprima

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

am încercat-o pe gcc v3.4.6 pe Solaris SPARC 64 biți și rezultatul este același cu byte1 și byte2declarat ca char.

TL;DR

mascarea este de a evita extinderea semn implicit.

EDIT: am verificat, este același comportament în c++.

EDIT2: după cum se solicită explicația extensiei semnului.Extensia semnului este o consecință a modului în care c evaluează expresiile. Există o regulă în C numită regulă de promovare. C va arunca implicit toate tipurile mici la int înainte de a face evaluarea. Să vedem ce se întâmplă cu expresia noastră:

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

byte1 este o variabilă care conține modelul de biți 0xFF. Dacă char este unsigned această valoare este interpretată ca 255, dacă este signed este -128. Când efectuați calculul, C va extinde valoarea la o dimensiune int(în general 16 sau 32 de biți). Aceasta înseamnă că dacă variabila este unsigned și vom păstra valoarea 255, modelul de biți al acelei valori ca int va fi 0x000000FF. Dacă este signed vrem valoarea -128 care model de biți este 0xfffffffff. Semnul a fost extins la dimensiunea tempory utilizate pentru a face calculul.Și astfel oring temporar va produce rezultatul greșit.

la asamblarea x86 se face cu instrucțiuneamovsx (movzx pentru extinderea zero). Alte CPU-uri aveau alte instrucțiuni pentru asta (6809 avea SEX).

Lasă un răspuns

Adresa ta de email nu va fi publicată.