算术运算导致溢出_位运算总结

Bit manipulation summary

一、位运算的性质

1、位运算的优先级。

与算术运算(加减同优先级)不同,"与" "异或"“或”的优先级不同。
JAVA中:
“与”>“异或”>“或”
(3 | 1) & 2  = 2
3 | 1 & 2 = 3
与我们的习惯差异较大,建议多用括号。


2、位运算的单向性

位运算中“与”、“或”会造成信息丢失,他们是单向运算,不可逆运算。

1 & x = y;
知道x 可以求出y,
知道y 不可能求出x。
当y = 0, x 可能等于0,2,6……
"左移"“右移”在数据溢出时也会信息丢失。

“异或”不会造成信息丢失,而且具有很好的性质。

x ^ a = y;
当a 确定时,x与y 一一对应,且
x = y ^ a;
正因为异或不会造成信息丢失,异或可以进行算杂的交换运算;(否则在交换中信息丢失,会导致无法还原)
由于位运算中可能的信息丢失,位运算的优先级特别重要,顺序不同,丢失的信息不同,结果就不同。


3、运算规律

交换律:
a | b = b | a
a & b = b & a
a ^ b = b ^ a

结合律:
(3 | 1) & 2  = 2
3 | 1 & 2 = 3
证明结合律是失效的。


分配律:
( 4 | 3 )^ 1 = 6;
( 4 ^ 1 ) | (3 ^ 1 ) = 7
证明分配律是失效的。
因此,一般情况下,结合律和分配律是失效的,只有交换律能安全使用。

二、运算的技巧
为了避免技巧太多,过于庞大复杂不利于理解和记忆,

以下甄选的技巧都没有循环控制语句,是时间复杂度为O(1)的运算,性质很棒。

int a;

1、int最大值
(1<<31)-1

2、int最小值
1<<31

3、取绝对值
a ^ (a>>31) - (a>>31);

4、全1
~0 = -1 = 0xffffffff(1个f 4位,8个f 32位)

5、负数
-a = ~a + 1


6、
a & a = a
a | a = a
a ^ a = 0 (去重常用)

7、
a & 0 = 0
a | 0 = a
a ^ 0 = a (置换常用)

8、
a & (~0) = a
a | (~0) = ~0
a ^ (~0) = ~a (取反的另一种写法)


9、置换
a ^= b;
b ^= a;
a ^= b;

10、判断奇偶(取出最后一位)
a & 1 等价于 a % 2(结果等于0为偶,位运算效率高)


11、比较两值是否相等
a ^ b ==0

12、判断最高位是否为1
a<0

13、判断符号是否相同
a ^ b >= 0

14、取出第i+1位
a & (1<<i)

15、i+1位 置1
a |=1<<i

16、i+1位 置0
a &=~(1<<i)

17、i+1位 反转
a ^ (1<<i)

18、在对应i+1位,插入b的对应位;
a |=1<<i; (a的bit位置1)
a & (b & 1<<i) (与b的bit位相与)
(置1后相与=置0后相或)

19、保留最后i-1位;
a & ((1<<i)-1)

20、清零最后i-1位;
a & ~((1<<i)-1)

21、删除最后的1;
a & (a-1) (可用于判断2的幂数)

22、仅保留最后一个1;
a & (-a)

23、得到最高位的1;
a = a |(a>>1);
a = a |(a>>2);
a = a |(a>>4);
a = a |(a>>8);
a = a |(a>>16);
return (a+1)>>1;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值