mitä ja 0xFF tekee?

ja kokonaisluku, jolla on 0xFF, jättää jäljelle vain vähiten merkitsevän tavun. Esimerkiksi ensimmäisen tavun saa short s kirjoittamalla s & 0xFF. Tämä on tyypillisesti kutsutaan ”masking”. Jos byte1 on joko yksittäinen tavutyyppi (kuten uint8_t) tai on jo alle 256 (ja sen seurauksena kaikki nollat lukuun ottamatta vähiten merkitsevää tavua), ei tarvitse peittää korkeampia bittejä, koska ne ovat jo nollia.

Katso tristopiaPatrick Schlüterin vastaus alta, milloin signeerattujen tyyppien kanssa voi työskennellä. Kun teet bitwise operaatioita, suosittelen työskentelyä vain allekirjoittamattomien tyyppien kanssa.

jos byte1 on 8-bittinen kokonaisluku, niin se on turhaa – jos se on enemmän kuin 8 bittiä, se antaa periaatteessa arvon viimeiset 8 bittiä:

 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

toisen lausekkeen vaara tulee, jos Tyyppi byte1 on char. Tällöin joissain toteutuksissa se voi olla signed char, jolloin sitä arvioitaessa päädytään merkkilaajennukseen.

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

tulostetaan

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

kokeilin sitä gcc: llä v3. 4.6 Solaris SPARCILLA 64 bittiä ja tulos on sama byte1 ja byte2 ilmoitettu char.

TL; DR

peittämisellä pyritään välttämään implisiittinen merkin laajentaminen.

EDIT: tarkistin, se on sama käyttäytyminen C++: ssa.

EDIT2: pyydetyn selityksen mukainen kyltin laajennus.Sign extension on seurausta tavasta, jolla C arvioi ilmaisuja. C: ssä on sääntö nimeltä ylennyssääntö. C laskee implisiittisesti kaikki pienet tyypit arvoon int ennen arvioinnin tekemistä. Katsotaan, mitä tapahtuu ilmaisullemme:

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

byte1 on muuttuja, joka sisältää bittikuvion 0xFF. Jos char on unsigned tuo arvo tulkitaan arvoksi 255, jos se on signed se on -128. Laskentaa tehtäessä C laajentaa arvon int kokoiseksi (yleensä 16 tai 32 bittiä). Tämä tarkoittaa, että jos muuttuja on unsigned ja pidämme arvon 255, kyseisen arvon bittikuvio arvona int on 0x000000ff. Jos se on signed haluamme arvon -128 mikä bittikuvio on 0xFFFFFFFF. Merkki laajennettiin laskutoimituksessa käytetyn temporyn kokoiseksi.Ja siten tilapäisen välittäminen tuottaa väärän tuloksen.

x86-kokoonpanolla se tehdään movsx – ohjeella (movzx nollapidennykselle). Muissa suorittimissa oli siihen muita ohjeita (6809: llä oli SEX).

Vastaa

Sähköpostiosoitettasi ei julkaista.