簡體   English   中英

AND 0xFF 有什么作用?

[英]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 byte1byte2相同。

TL; 博士

屏蔽是為了避免隱式符號擴展。

編輯:我檢查過,它在 C++ 中是相同的行為。

EDIT2 :根據要求解釋符號擴展。 符號擴展是 C 計算表達式方式的結果。 C 中有一個規則叫做提升規則 在進行計算之前,C 將隱式地將所有小類型轉換為int 讓我們看看我們的表達式會發生什么:

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

byte1是一個包含位模式 0xFF 的變量。 如果charunsigned ,則該值被解釋為 255,如果它是有signed ,則它是 -128。 在進行計算時,C 會將值擴展為int大小(通常為 16 或 32 位)。 這意味着如果變量是unsigned並且我們將保留值 255,那么作為int值的位模式將為 0x000000FF。 如果它是有signed我們需要值 -128,位模式是 0xFFFFFFFF。 符號擴展到用於進行計算的臨時的大小。 因此 oring 臨時將產生錯誤的結果。

在 x86 匯編上,它是通過movsx指令完成的( movzx表示零擴展)。 其他 CPU 對此有其他指令(6809 有SEX )。

假設您的byte1是一個字節(8 位),當您對一個字節與 0xFF 進行按位與運算時,您將獲得相同的字節。

所以byte1byte1 & 0xFF相同

byte101001101 ,然后byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1

如果 byte1 是其他類型的 4 字節整數,則按位 AND 與 0xFF 會為您留下 byte1 的最低有效字節(8 位)。

byte1 & 0xff確保只有8的至少顯著位byte1可以是非零的。

如果byte1是已經僅具有8位(例如,無符號類型char在某些情況下,或unsigned char在大多數),它不會有任何區別/是完全不必要的。

如果byte1是有符號類型或具有超過 8 位的類型(例如, shortintlong ),並且設置了除 8 個最低有效位之外的任何位,則將存在差異(即,它將使那些位為零) or ing 與另一個變量之前的高位,因此or此操作數僅影響結果的 8 個最低有效位)。

它清除所有不在第一個字節中的位

& 0xFF本身僅確保如果字節長於 8 位(語言標准允許),則其余部分將被忽略。

這似乎也能正常工作?

如果結果最終大於SHRT_MAX ,則會出現未定義的行為。 在這方面,兩者的效果都一樣差。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM