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;