位运算的简单理解

既然都有了原码,反码,补码的概念,那位运算也就呼之欲出了。
何为位运算,就是对二进制的0和1进行操作,在代码中可以进行高低位的截取,哈希计算,甚至用在乘除法算法中。


位运算的几个操作符号:<<(左移),>>(右移),&(与),|(或),^(异或)
<<操作符:二进制左移
举例:1<<1底层实际是:0000 0001左移1位变0000 0010即2
>>操作符:二进制右移
举例:2>>1底层实际是:0000 0010右移1位变0000 0001即1
&操作符:二进制位上只有都为1才是1
举例:2&1底层实际是:0000 0010 & 0000 0001变0000 0000即0
举例:3&1底层实际是:0000 0011 & 0000 0001变0000 0001即1
|操作符:二进制位上只要有1个为1即1
举例:2|1底层实际是:0000 0010 | 0000 0001变0000 0011即3
^操作符:二进制位只有当不同时才为1,即0和1为1,1和1为0
举例:2^1底层实际是:0000 0010 ^ 0000 0001变0000 0011即3

可以得出一个结论:向右移动1位的时候近似表示除以2

但是需要注意的是并不是一定,举个例子:
十进制的技术转换为二进制后,向右移动的时候,最右边的1将直接抹去,说明向右移对于奇数并非完全相当于除以2.

注意注意!很重要的一点就是位运算操作是针对补码进行的,如果是正数,补码还是原码不影响,关键是负数,对负数进行位操作时,一定要先转换为补码才行。
具体的原码补码可以参考这篇:
原码,反码,补码的简单理解

还有个结论:在左移<<和右移>>两种运算中,符号位均参与移动,除负数往右边移动,高位补1之外,其他情况均在空位处补0(来自码出高效)

注意:
负数的位运算要先转换为补码,如果最后的结果的最高位为1还需要进行补码操作
参考:
https://blog.csdn.net/u013790019/article/details/44627719

位运算的其他运用:用来代替&&和||。
这个时候你就会问了 &和&&还有|和||不是一个作用吗,的确这两者的运算都可以作用于条件表达式,但是后者&&和||会发生短路现象,举例:

boolean a = true;
boolean b = true;
boolean c = (a=(1==2)) && (b=(1==2));

结果是:

true

结果分析:
因为&&前边的表达式(1==2)结果为false,触发短路,直接退出,最后a的值为false ,b的值为true。如果吧&&换成按位与&,则执行的结果为a与b都是false
同理||和|一样。

但是注意:逻辑与&和逻辑或|只能对布尔类型的条件表达式进行运算,像7&8这种运算表达式是错误的。

再来刷两道位运算的题目更加了解下:

异或操作符题目:

136. 只出现一次的数字

题解:

class Solution {
    public int singleNumber(int[] nums) {
         int temp=0;
        for(int i=0;i<nums.length;i++){
            temp^=nums[i];
        }
        return temp;
    }
}

综合题目:

137. 只出现一次的数字 II

题解:
https://blog.csdn.net/w8253497062015/article/details/80058180

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值