關於位運算的所有基礎知識和 實際應用總結

2021-09-13 17:41:02 字數 4229 閱讀 7486

<<   左移

>>   右移

>>>  無符號右移

&    位與

|    位或

~    位非

^    位異或

其中位非(~)是一元運算子,其他六個都是二元運算子。

這些位運算子都是作用在二進位制的數上的,先列乙個表描述一下這幾種位運算子:

下面來一一介紹一下這幾種位運算子

位運算子介紹

1、<< 左移

兩個左尖括號表示左移運算子,運算子規則是:各二進位全部左移若干位,高位丟棄,低位補0。

例如:6 << 2 = 24

0000 0000 0000 0000 0000 0000 0000 0110     -> 6

0000 0000 0000 0000 0000 0000 0001 1100     -> 6 << 2 = 24

我們將6的二進位向左移動兩位,低位補上兩個0,高位丟棄,得出來的結果就是24。

左移常被用來做 * (2 ^ n)的運算,因為直接基於二進位制運算,所以左移效率比 * (2 ^ n)高。

2、>> 右移

兩個右尖括號表示右移運算子,運算子規則是:各二進位全部右移若干位,正數高位補0,負數高位補1,低位丟棄。

例如: 12 >> 2 = 3

0000 0000 0000 0000 0000 0000 0000 1100     -> 12

0000 0000 0000 0000 0000 0000 0000 0011     -> 12 >> 2 = 3

因為12是正數,右移過程中高位補上兩個0,低位丟棄,得出來的結果就是3。

例如:-12 >> 2 = -3

1111 1111 1111 1111 1111 1111 1111 0100    -> -12

1111 1111 1111 1111 1111 1111 1111 1101    -> -12 >> 2 = -3

因為-12是負數,右移過程中高位補上兩個1,低位丟棄,得出來的結果就是-3。

右移常被用來做 / (2 ^ n)的運算,因為直接基於二進位制運算,所以右移效率比 / (2 ^ n)高。

3、>>> 無符號右移

三個右尖括號表示無符號右移運算子,運算子規則是:各二進位全部右移若干位,高位補0,低位丟棄。

例如: 12 >>> 2 = 3

0000 0000 0000 0000 0000 0000 0000 1100     -> 12

0000 0000 0000 0000 0000 0000 0000 0011     -> 12 >>> 2 = 3

我們將12的二進位向右移動兩位,高位補上兩個0,低位丟棄,得出來的結果就是24。

例如:-12 >>> 2 = 1073741821

1111 1111 1111 1111 1111 1111 1111 0100    -> -12

0011 1111 1111 1111 1111 1111 1111 1101    -> -12 >> 2 = 1073741821

我們將-12的二進位向右移動兩位,高位補上兩個0,低位丟棄,得出來的結果就是1073741821。

4、& 位與

運算規則是:當運算子兩邊相同位置都是1時,結果返回1,其他情況都返回0。

例如:3 & 5 = 1

0000 0000 0000 0000 0000 0000 0000 0011     -> 3

0000 0000 0000 0000 0000 0000 0000 0101     -> 5

0000 0000 0000 0000 0000 0000 0000 0001     -> 3 & 5 = 1

其中3和5的只有第一位共同為1,所以3 & 5 = 1。

5、| 位或

運算規則是:當運算子兩邊相同位置都是0時,結果返回0,其他情況都返回1。

例如:3 | 5 = 1

0000 0000 0000 0000 0000 0000 0000 0011     -> 3

0000 0000 0000 0000 0000 0000 0000 0101     -> 5

0000 0000 0000 0000 0000 0000 0000 0111     -> 3 \| 5 = 7

其中3和5的第一到第三位都有不為0的,所以 3 | 5 = 7。

6、~ 位非

運算規則是:將運算子後二進位制數反轉,0變1,1變 。

例如:~ 3 = -4

0000 0000 0000 0000 0000 0000 0000 0011     -> 3

1111 1111 1111 1111 1111 1111 1111 1100     -> ~ 3 = -4

將3的所有二進位制位全部反轉,所以~ 3 = -4。

7、^ 位異或

運算規則是:當運算子兩邊相同位置都是相同,結果返回0,不相同時返回1。

例如:3 ^ 5 = 1

0000 0000 0000 0000 0000 0000 0000 0011     -> 3

0000 0000 0000 0000 0000 0000 0000 0101     -> 5

0000 0000 0000 0000 0000 0000 0000 0110     -> 3 ^ 5 = 6

其中3和5的第一和第三位不相同,所以 3 ^ 5 = 6。

位運算子使用技巧

1、判斷奇偶數

我們可以利用 & 運算子的特性,來判斷二進位制數第一位是0還是1。

用if ((a & 1) == 0) 代替 if (a % 2 == 0)來判斷a是不是偶數。

2、交換兩個數

借助臨時變數

通常我們交換兩個數會使用乙個臨時變數來幫忙:

int temp = a;

a = b;

b = temp;

借助累加和

如果考慮到記憶體,不希望使用臨時變數(其實就是為了炫酷),可以這樣實現:

a = a + b;

b = a - b;

a = a - b;

從數學角度來分析一下(這個解釋很違和,需要在乙個頻道才能看懂): 

- 第一步:a = a + b 

- 第二步:b = a - b = (a + b) - b = a 

- 第三步:a = a - b = (a + b) - b = (a + b) - a = b

使用 ^ 位運算子

如果想要更炫酷一點可以使用 ^ 來幫忙實現: 

先來了解一下 ^ 的幾個特性: 

- a ^ a = 0 

- a ^ 0 = a 

- (a ^ b) ^ c = a ^ (b ^ c)

a ^= b;

b ^= a;

a ^= b;

從數學角度來分析一下這個解釋也很違和,需要在乙個頻道才能看懂): 

- 第一步:a = a ^ b 

- 第二步:b = a ^ b = (a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a 

- 第三步:a = a ^ b = (a ^ b) ^ b = (a ^ a) ^ b = b ^ 0 = b

3、取餘

其實取餘演算法和上面的判斷奇偶數原理是一樣的。

比如說我們要讓a對16進行取餘,那麼就可以讓 a & 15 得出來的結果就是餘數。

可以看出15的二進位制表示為:

0000 0000 0000 0000 0000 0000 0000 1111

所以 a & 15 返回值就是a二進位制的最低四位,也就是 a & 15 = a / 16。

使用 & 來進行取餘的演算法比使用 / 效率高很多,雖然只能對2^n的數值進行取餘計算,但是在jdk原始碼中也是經常被使用到,比如說hashmap中判斷key在hash桶中的位置。

4、其他簡單應用

求相反數: ~a + 1

求絕對值: a >> 31 == 0 ? a : (~a + 1)

位運算基礎知識

位運算子主要針對二進位制,它包括了 與 非 或 異或 從表面上看似乎有點像邏輯運算子,但邏輯運算子是針對兩個關係運算子來進行邏輯運算,而位運算子主要針對兩個二進位制數的位進行邏輯運算。下面詳細介紹每個位運算子。1 與運算子 與運算子用符號 表示,其使用規律如下 兩個運算元中位都為1,結果才為1,否則...

位運算的基礎知識

位運算常見符號 我只會這麼多 舉例均為二進位制 與運算子 兩位同時為 1 結果才為 1 否則為0 例 1 0 0 0 0 0 1 1 1 110 111 110 或運算子 參加運算的兩個物件只要有乙個為1,其值為1 例 1 1 1 1 0 1 0 0 0 110 111 111 異或 同為0,異為1...

位運算的基礎知識整理

按位與 如果兩個相應的二進位制位都為1,則結果為1,否則結果為0。按位或 兩個相應的二進位制位中只要有乙個為1,則結果為1,否則結果為0。按位異或 若參加運算的兩個二進位制位值相同,則結果為0,否則結果為1。取反 對乙個二進位制數按位取反,即將0變為1,將1變為0。左移 用來將乙個數的各二進位制位全...