首页 > 代码库 > 神奇的位运算

神奇的位运算

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)

神奇的位运算