Vad gör och 0xFF?

och ett heltal med 0xFF lämnar endast den minst signifikanta byten. Till exempel, för att få den första byten i en short s kan du skriva s & 0xFF. Detta kallas vanligtvis ”maskering”. Om byte1 antingen är en enda byte-typ (som uint8_t) eller redan är mindre än 256 (och som ett resultat är alla nollor utom den minst signifikanta byten) behöver man inte maskera de högre bitarna, eftersom de redan är noll.

se tristopiaPatrick Schl Jacobters svar nedan när du kanske arbetar med signerade typer. När du gör bitvis operationer rekommenderar jag att du bara arbetar med osignerade typer.

om byte1 är en 8-bitars heltalstyp är det meningslöst – om det är mer än 8 bitar kommer det i huvudsak att ge dig de sista 8 bitarna av värdet:

 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

faren för det andra uttrycket kommer om typen byte1 är char. I så fall kan vissa implementeringar ha det signed char, vilket kommer att resultera i teckenförlängning vid utvärdering.

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

kommer att skriva ut

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

jag försökte det på gcc v3.4.6 på Solaris SPARC 64 bit och resultatet är detsamma med byte1 och byte2deklarerade som char.

TL;DR

maskeringen är att undvika implicit teckenförlängning.

redigera: jag kollade, det är samma beteende i C++.

EDIT2: som begärd förklaring av teckenförlängning.Teckenförlängning är en följd av hur C utvärderar uttryck. Det finns en regel i C som kallas promotion rule. C kommer implicit att kasta alla små typer till int innan utvärderingen görs. Låt oss se vad som händer med vårt uttryck:

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

byte1 är en variabel som innehåller bitmönster 0xFF. Om char är unsigned tolkas värdet som 255, om det är signed är det -128. När du gör beräkningen kommer C att utöka värdet till en int storlek (16 eller 32 bitar i allmänhet). Det betyder att om variabeln är unsigned och vi kommer att behålla värdet 255, kommer bitmönstret för det värdet som int att vara 0x000000FF. Om det är signed vill vi ha värdet -128 vilket bitmönster är 0xFFFFFFFF. Tecknet utvidgades till storleken på tempory som användes för att göra beräkningen.Och sålunda kommer det tillfälliga att ge fel resultat.

på x86-montering görs det med movsx – instruktionen (movzx för nollförlängningen). Andra CPU: er hade andra instruktioner för det (6809 hade SEX).

Lämna ett svar

Din e-postadress kommer inte publiceras.