聊聊位運算吧

2022-06-14 07:45:11 字數 3785 閱讀 9187

先說說 什麼是位運算,程式中的所有數在計算機記憶體中都是以二進位制的形式儲存的。位運算就是直接對整數在記憶體中的二進位制位進行操作。說白的位運算就是將整數在記憶體中的二進位制的進行運算。

運算符號

意義運算物件型別

運算結果型別

物件數例項

~位邏輯非運算

整型,字元型整型1

~a&位邏輯與運算

2a & b

|位邏輯或運算

2a | b

^位邏輯異或運算

2a ^ b

<< 

位左移運算

2a<<4

>> 

位右移運算

2a>>2

1. ~ 位求反

運算子規則是:將運算子後二進位制數反轉,0變1,1變 0,所以對乙個數取反偶數次結果是它本身。

例如:0000 0000 0000 0000 0000 0000 0000 0011 -> 3

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

常用場景:

求相反數: ~a + 1

2. << 左移

運算子規則是:各二進位全部左移若干位,高位丟棄,低位補0。

例如:6 << 2 = 24

0000 0000 0000 0000 0000 0000 0000 0110 -> 6

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

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

常用場景:

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

3. >> 右移

運算子規則是:各二進位全部右移若干位,正數高位補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)高。

4. >>> 無符號右移

運算子規則是:各二進位全部右移若干位,高位補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。

5. & 位與

運算子規則是:運算子兩邊有0,結果就為0 ,只有當兩邊同時為1是,結果才為1。

如下:0 & 0 = 0;     0 & 1 = 0;     1 & 0 = 0;       1 & 1= 1;

例如:3&5  

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

位與運算的特殊用途:

1.清零(將乙個單元與0進行位與運算結果為零)

2.取乙個數指定位(例如取num=1010 1101的低四位 則將num&0xf得到0000 1101)。

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

6. | 位或

運算規則就是 運算子兩邊有1,結果就為1 ,只有當兩邊同時為0是,結果才為0。

如下:0 | 0 = 0;  0 | 1 = 1;  1 | 0 = 1;   1 | 1 = 1 ;

例如:3|5 

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

另,負數按補碼形式參加按位或運算。

使用場景:

下面這個方法是摘自hashmap類,這個演算法來修改使用者使用構造器傳進來的size的,這個演算法是使用移位和或結合來實現的,效能上比迴圈判斷要好。

publicstaticfinalinttablesizefor(intcap)

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

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

intt = a;

a = b;

b = t;

使用 ^ 位運算子(裝逼必備)

a ^= b;

b ^= a;

a ^= b;

聊聊位運算那些事(2)

引發學習位運算的原因是在網上瀏覽到了幾道題 有乙個給定的陣列,其中僅有乙個元素出現了一次,而其他的元素出現了兩次。問如何找出這個僅出現一次的元素呢?解 其實看到這一題的第一反應是利用陣列下標法。但是它的空間複雜度是o n 是時間複雜度是o n 但是我們可不可再優化以下,盡量降低它的複雜度?緊接著,又...

有空聊聊天吧

下午和zj在南區一棟樓下面聊天。她說的一些事情讓我不得不再次把自己對一些人的看法重新歸置。講到愛情,因為她的一些事。用自殘的方式博取愛情在我和她看來都很幼稚,和她說的時候,我心裡偷偷冒了下冷汗,我也做過類似的事情,但不是用以換取女生青睞的籌碼。和她講話的時候我就在想,愛情是什麼呢,難道愛,可以讓乙個...

我們聊聊快排吧

最近一直在看 程式設計珠璣 第二版這一本書,裡面的東西真的很實用,以前也看過不少講解快排的書,但是在程式設計珠璣上看到的講解是我見過最好理解,也是最詳細的,從效率和空間以及實現等各個方面都做了詳細說明,並比較了幾種變形的快排的效率,所以在這把我看到的內容寫出來記錄,留著以後忘了的時候看。1.1.插入...