Og et heltall med 0xFF
etterlater bare den minst signifikante byten. For eksempel, for å få den første byten i en short s
, kan du skrive s & 0xFF
. Dette er vanligvis referert til som «maskering». Hvis byte1
enten er en enkeltbytetype (som uint8_t
) eller allerede er mindre enn 256 (og som et resultat er alle nuller unntatt den minst signifikante byten), er det ikke nødvendig å maskere de høyere bitene, da de allerede er null.
Se tristopiaPatrick Schlü svar nedenfor når du kanskje jobber med signerte typer. Når du gjør bitvis operasjoner, anbefaler jeg at du bare arbeider med usignerte typer.
hvis byte1
er en 8-biters heltallstype, er det meningsløst – hvis det er mer enn 8 biter, vil det i hovedsak gi deg de siste 8 bitene av verdien:
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 for det andre uttrykket kommer hvis typen byte1
er char
. I så fall kan noen implementeringer ha det signed char
, noe som vil resultere i skiltutvidelse når man vurderer.
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);
vil skrive ut
value1=4224 1080 rightvalue2=65408 ff80 wrong!!
jeg prøvde det på gcc v3.4.6 På Solaris SPARC 64 bit og resultatet er det samme med byte1
og byte2
erklært som char
.
TL;DR
maskeringen er å unngå implisitt tegnutvidelse.
REDIGER: jeg sjekket, det er samme oppførsel I C++.
EDIT2: som forespurt forklaring av tegnutvidelse.Tegnutvidelse er en konsekvens Av Måten C evaluerer uttrykk på. Det er en regel I C som kalles promotion rule. C vil implisitt kaste alle små typer til int
før du gjør evalueringen. La oss se hva som skjer med vårt uttrykk:
unsigned short value2 = ((byte2 << 8) | byte1);
byte1
er en variabel som inneholder bitmønster 0xFF. Hvis char
er unsigned
den verdien tolkes som 255, hvis den er signed
, er den -128. Når du gjør beregningen, vil C utvide verdien til en int
størrelse (16 eller 32 bits generelt). Dette betyr at hvis variabelen er unsigned
og vi vil beholde verdien 255, vil bitmønsteret av den verdien som int
være 0x000000FF. Hvis det er signed
vil vi ha verdien -128 som bitmønster er 0xFFFFFFFF. Tegnet ble utvidet til størrelsen på tempory brukes til å gjøre beregningen.Og dermed oring den midlertidige vil gi feil resultat.
på x86-montering er det gjort med instruksjonen movsx
(movzx
for nullutvidelsen). Andre CPU hadde andre instruksjoner for det (6809 hadde SEX
).