co dělá a 0xFF dělat?

a celé číslo s 0xFF ponechává pouze nejméně významný bajt. Chcete-li například získat první bajt v short s, můžete napsat s & 0xFF. Toto je obvykle označováno jako „maskování“. Pokud byte1 je buď jednobajtový Typ (jako uint8_t), nebo je již menší než 256 (a výsledkem jsou všechny nuly kromě nejméně významného bajtu) , není třeba maskovat vyšší bity, protože jsou již nulové.

viz odpověď tristopiaPatrick Schlüter níže, když můžete pracovat s podepsanými typy. Při provádění bitových operací doporučuji pracovat pouze s nepodepsanými typy.

pokud byte1 je 8bitový celočíselný Typ, pak je to zbytečné – pokud je to více než 8 bitů, v podstatě vám dá posledních 8 bitů hodnoty:

 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

nebezpečí druhého výrazu přichází, pokud je typ byte1 char. V takovém případě mohou mít některé implementace signed char, což bude mít za následek rozšíření znaménka při hodnocení.

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

vytiskne

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

zkoušel jsem to na gcc v3. 4.6 na bitu Solaris SPARC 64 a výsledek je stejný s byte1 a byte2 deklarovaným jako char.

TL; DR

maskování má zabránit implicitnímu rozšíření znaku.

upravit: zkontroloval jsem, je to stejné chování v C++.

EDIT2: jak bylo požadováno vysvětlení rozšíření znamení.Rozšíření znaku je důsledkem způsobu, jakým C hodnotí výrazy. V C je pravidlo zvané pravidlo propagace. C implicitně odevzdá všechny malé typy na int před provedením hodnocení. Podívejme se, co se stane s naším výrazem:

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

byte1 je proměnná obsahující bitový vzor 0xFF. Pokud je char unsigned, je tato hodnota interpretována jako 255, pokud je signed je to -128. Při výpočtu C rozšíří hodnotu na velikost int (obecně 16 nebo 32 bitů). To znamená, že pokud je proměnná unsigned a ponecháme hodnotu 255, bitový vzor této hodnoty jako int bude 0x000000FF. Pokud je signed, chceme hodnotu -128, který bitový vzor je 0xFFFFFFFF. Značka byla rozšířena na velikost tempory použité k výpočtu.A tak oring dočasné přinese špatný výsledek.

v sestavě x86 se provádí instrukcí movsx (movzx pro nulovou extend). Ostatní CPU měly jiné pokyny pro to (6809 měl SEX).

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.