首页 > 代码库 > 神奇的位运算
神奇的位运算
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)
神奇的位运算