神奇的位運算

Java 的<< 和 >> 都是帶符號移位。在不溢出的情況下,相當於乘以或除以2.在溢出的情況下,也就是符號位被移出,此時就會發生正數變負數,負數變正數的錯誤情況。

1、獲取 int 最小值: 

        1<<31

        1左移31位,此時變成只有符號位爲1,其餘爲都爲0,即80000000H。此時該值爲int類型的最小數 -2147483648。

2、獲取 int 的最大值:

有三種寫法:

        (1<<31)-1 :即用最小的整數減去1,結果會溢出爲最大的整數,此時內存狀態爲 7FFFFFFFFF,即爲 2147483647。

        (1<< -1) -1:同上,左移-1和左移31其實是一樣的,因爲會對32取餘數,其實都是移動了31位。

        -(1<<-1)-1 :左移-1位之後,變爲最小整數,此時取相反數則變爲 2147483648(其實內存中位狀態沒變),減一即爲 2147483647。

3、不用臨時變量,交換 a 和 b :

        a^=b;
        b^=a;
        a^=b;

推導過程如下:

        a^=b;
        b=a^b=a^b^b = a;
        a=a^b = (a^b)^(a)=b;

4、對n取絕對值:(n^(n>>31))-(n>>31)

首先對於n來說,有如下公式: 

        整數對 -1 異或,都相當於取相反數減一。n^(-1)=(-n)-1 
        n的相反數-n=~n+1

那麼,對於公式,(n^(n>>31))-(n>>31),

        當n>=0時,化簡爲 n^0-0=n。

        當 n<0 時,化簡爲 n^(-1)-(-1)=n^(-1)+1 =(-n)-1+1=-n。

5、求a 和 b的最大值:b&((a-b)>>31) | a&(~(a-b)>>31)

        當 a>=b時,公式化簡爲 b&0 | a&(-1) = 0|a = a;

        當 a<b  時,公式化簡爲 b&(-1) | a&0 = b|0 =b;

6、求a 和 b的最小值:b&((b-a)>>31) | a&(~(b-a)>>31)

原理同 5.

7、判斷a b符號是否相同:(a^b)>0
8、求2的n次方:2<<(n-1)
9、判斷n是否是2的n次冪:(n&(n-1))==0

原理:如果n位2的n次冪,則n內存分佈肯定爲 100000……,則n-1的分佈爲 11111111……。n&(n-1)肯定爲0。

10、求a b的平均值: (x+y)>>1
11、取n的第m位:(n>>(m-1)) & 1
12、將n的第m位置1:(1<<(m-1)) | n
13、將n的第m位置0:(~(1<<(m-1))) & n
14、將x在a b 之間反轉(if(x==a) x = b; ):x = a^b^x;

即相當於:if(x==a) x=b;  if (x==b) x=a;

15、判斷奇偶性:n&1==0
16、正整數對2的冪取模:n mod 2^k = n&((1<<k)-1)
發佈了86 篇原創文章 · 獲贊 65 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章