[英]What does AND 0xFF do?
在以下代碼中:
short = ((byte2 << 8) | (byte1 & 0xFF))
&0xFF
的目的是什么? 因為有時我看到它寫成:
short = ((byte2 << 8) | byte1)
這似乎也能正常工作?
如果byte1
是一個 8 位整數類型,那么它是沒有意義的——如果它超過 8 位,它基本上會給你值的最后 8 位:
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
與0xFF
的整數只留下最低有效字節。 例如,要獲取short s
的第一個字節,您可以編寫s & 0xFF
。 這通常稱為“掩蔽”。 如果byte1
是單字節類型(如uint8_t
)或已經小於 256(因此除最低有效字節外全為零),則無需屏蔽高位,因為它們已經為零。
當您可能使用簽名類型時,請參閱
下面的 tristopia
Patrick Schlüter 的回答。 在進行按位運算時,我建議只使用無符號類型。
如果byte1
的類型是char
,則第二個表達式的危險就來了。 在這種情況下,某些實現可以將其signed char
,這將在評估時導致符號擴展。
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);
將打印
value1=4224 1080 right
value2=65408 ff80 wrong!!
我在 Solaris SPARC 64 位上的 gcc v3.4.6 上進行了嘗試,結果與聲明為char
byte1
和byte2
相同。
TL; 博士
屏蔽是為了避免隱式符號擴展。
編輯:我檢查過,它在 C++ 中是相同的行為。
EDIT2 :根據要求解釋符號擴展。 符號擴展是 C 計算表達式方式的結果。 C 中有一個規則叫做提升規則。 在進行計算之前,C 將隱式地將所有小類型轉換為int
。 讓我們看看我們的表達式會發生什么:
unsigned short value2 = ((byte2 << 8) | byte1);
byte1
是一個包含位模式 0xFF 的變量。 如果char
是unsigned
,則該值被解釋為 255,如果它是有signed
,則它是 -128。 在進行計算時,C 會將值擴展為int
大小(通常為 16 或 32 位)。 這意味着如果變量是unsigned
並且我們將保留值 255,那么作為int
值的位模式將為 0x000000FF。 如果它是有signed
我們需要值 -128,位模式是 0xFFFFFFFF。 符號擴展到用於進行計算的臨時的大小。 因此 oring 臨時將產生錯誤的結果。
在 x86 匯編上,它是通過movsx
指令完成的( movzx
表示零擴展)。 其他 CPU 對此有其他指令(6809 有SEX
)。
假設您的byte1
是一個字節(8 位),當您對一個字節與 0xFF 進行按位與運算時,您將獲得相同的字節。
所以byte1
與byte1 & 0xFF
相同
說byte1
是01001101
,然后byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1
如果 byte1 是其他類型的 4 字節整數,則按位 AND 與 0xFF 會為您留下 byte1 的最低有效字節(8 位)。
在byte1 & 0xff
確保只有8的至少顯著位byte1
可以是非零的。
如果byte1
是已經僅具有8位(例如,無符號類型char
在某些情況下,或unsigned char
在大多數),它不會有任何區別/是完全不必要的。
如果byte1
是有符號類型或具有超過 8 位的類型(例如, short
、 int
、 long
),並且設置了除 8 個最低有效位之外的任何位,則將存在差異(即,它將使那些位為零) or
ing 與另一個變量之前的高位,因此or
此操作數僅影響結果的 8 個最低有效位)。
它清除所有不在第一個字節中的位
& 0xFF
本身僅確保如果字節長於 8 位(語言標准允許),則其余部分將被忽略。
這似乎也能正常工作?
如果結果最終大於SHRT_MAX
,則會出現未定義的行為。 在這方面,兩者的效果都一樣差。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.