十六進制與二進制對應關系
十六進制和二進制之間的轉換非常直接,每個十六進制數字直接對應四個二進制位,并且十六進制相對二進制要更加簡潔,因此通常書寫位操作的代碼時會選擇使用十六進制來表示數值。
為了方便快速閱讀涉及位運算的源碼,我們首先需要了解十六進制的 16 個數字和二進制的對應關系,對應關系如下:
- 0對應0000
- 1對應0001
- 2對應0010
- 3對應0011
- 4對應0100
- 5對應0101
- 6對應0110
- 7對應0111
- 8對應1000
- 9對應1001
- A對應1010
- B對應1011
- C對應1100
- D對應1101
- E對應1110
- F對應1111
&
& 按位與(AND)操作。對于每一位,只有兩個操作數相對應的位都是1時,結果位才為1,否則為0。
示例:0x1234
& 0x4321
= 0x0220
計算思路:
16進制各位依次轉換為二進制,進行二進制對應位計算。
計算演示(從高位到低位):
1: 0001
4: 0100
0000: 0
2: 0010
3: 0011
0010: 2
3: 0011
2: 0010
0010: 2
4: 0100
1: 0001: 0
res: 0x0220
使用 uint16
僅是因為當前示例為 uint16
。
|
| 按位或(OR)操作。對于每一位,如果兩個操作數相應的位中至少有一個為1,則結果位為1,否則為0。
示例:0x1234
| 0x4321
= 0x5335
計算思路同 &,簡略計算步驟如下:
0x1234
轉二進制:0001 0010 0011 0100
0x4321
轉二進制:0100 0011 0010 0001
- 對每一位執行或操作:
0001 0010 0011 0100
0100 0011 0010 0001
-------------------
0101 0011 0011 0101
res: 0x5335
^
^ 異或操作(XOR)操作。對于每一位,如果兩個操作數對應的位一個為0一個為1,則結果位位1,否則為0。
示例:0x1234
^ 0x4321
= 0x5115
0x1234
轉二進制:0001 0010 0011 0100
0x4321
轉二進制:0100 0011 0010 0001
- 對每一位執行異或操作:
0001 0010 0011 0100
0100 0011 0010 0001
-------------------
0101 0001 0001 0101
res: 0x5335
&^
&^ 位清除(AND NOT)操作。對于每一位,如果第二操作數相應的位為1,則結果位為0,否則結果位為第一個操作數相應的位。
示例:0x1234
^ 0x4321
= 0x1014
0x1234
轉二進制:0001 0010 0011 0100
0x4321
轉二進制:0100 0011 0010 0001
- 對每一位執行操作:
0001 0010 0011 0100
0100 0011 0010 0001
-------------------
0001 0000 0001 0101
res: 0x1014
<<
<<
左移操作。將操作數的所有位向左移動指定的位數,右邊空出的位用0填充。
示例:0xFFFF
<< 1
= 0xFFFE
0xFFFF
轉二進制:1111 1111 1111 1111
- 所有位左移1位,并在末位填充0:
1111 1111 1111 1110
res: 0xFFFE
>>
>>
右移操作。將操作數的所有位向右移動指定的位數,左邊空出的位的填充方式取決于操作數的類型(對于無符號數用0填充,對于有符號數,通常用符號位填充,但這可能依賴于具體實現)。
無符號整數示例
0xF0
>> 2
= 0x3C
0xF0
轉二進制:1111 0000
- 所有位右移2位:
1111 0000
0011 1100
res: 0x3C
有符號整數示例
對有符號整數求右移我們需要首先知道補碼的計算方式
計算補碼
以 -16
為例:
- 使用二進制表示正
16
:0001 0000
- 取反(0變1,1變0):
1110 1111
- 加1:
1111 0000
右移
-16
>> 2
= -4
有符號整數:-16(十進制),補碼形式為 1111 0000
計算思路:將補碼所有位右移2位,高位補符號位(此處為1),得到結果也是補碼。
初始:1111 0000
,右移2位:1111 1100
反推十進制整數
將補碼 1111 1100
轉換為十進制需要:
- 取反:
0000 0011
- 加1得到:
0000 0100
- 轉換為十進制:
0000 0100
轉為十進制為4
- 加上符號:
-4