1、与运算介绍
与的概念:与运算是通过比较二进制位,同为1才为1,否则都为0
- 与运算的常用方式:
- 分配律:a&b=b&a
- 结合律:(a&b)&c = a&(b&c)
- 对于一个数(a)来说:
- a与1的结果如果为1,则这个数是奇数,如果为0,则这个数是偶数
- 任何数与0的结果都为0
- 一个正数与一个负数其结果一定为正数
- a与0xaaaaaaaa可以保留a的二进制位上偶数位上的1 (ps:0xaa… => 10101010 10101010 10101010 10101010)
- a与0x55555555可以保留a的二进制位上奇数位上的1 (ps:0x55… => 01010101 01010101 01010101 01010101)
- 两个数与的结果去与其中一个数,其结果还是两个数与的结果
2、与运算的简单使用
根据以上结论,我们来简单的做几个题测试一下它的作用。
- 题1:判断一个数的奇偶性:
题目分析: 根据以上结论,a与1的结果如果为1,则这个数是奇数,如果为0,则这个数是偶数
,因为一个奇数的最低二进制位必定为1,所以我们可以直接让这个数去和1做与运算,结果结果为1就是奇数,否则为偶数。
public static void main(String[] args){
int num = 12;
if((num&1)==1)
System.out.println("奇数");
else
System.out.println("偶数");
}
- 题二: 让一个数的二进制位上的奇偶位互换:
题目分析: 根据以上结论,a与0xaaaaaaaa可以保留a的二进制位上偶数位上的1, a与0x55555555可以保留a的二进制位上奇数位上的1
,这样,我们就能分别获取a的奇数位上的1的二进制数b,以及a的偶数位上的1的二进制数c,这个时候如果把b和c进行异或(^)运算,那么就会恢复成a,这样就刚好成对了。为了更加形象,下面我们来一段数据分析:
设一个数num = 9;
那么它的二进制表现形式为:00000000 00000000 00000000 00001001(正数的原码、反码、补码相同,三码合一)
0xaaaaaaaa的二进制形式为:10101010 10101010 10101010 10101010(进行与运算必须是在补码的基础上进行操作,负数的话需要先转换为补码)
0x55555555的二进制形式为:01010101 01010101 01010101 01010101
num&0xaaaaaaaa的结果b为: 00000000 00000000 00000000 00001000
num&0x55555555的结果c为: 00000000 00000000 00000000 00000001
这时候,如果我们把b和c异或一下,可以发现,它们又恢复成了num
b^c = 00000000 00000000 00000000 00001001,正好对应数字9,那么我们应该如何去交换奇偶的二进制位呢?通过观察,我们可以发现1001奇偶互换之后的数应该为0110,也就是6,而这个结果我们应该如何获得呢?这里就需要用到位运算了,前面我们分析过了,通过&0xaaaaaaaa和0x55555555可以分别保留偶数位和奇数为上的二进制数,那么我们只需要让保留了偶数位的结果右移一位,保留了奇数位的结果左移一位,然后再对他们进行异或操作,就能够得到二进制互换之后的数,分析清除之后,代码就很简单了,一句代码就能搞定:
public static int demo(int num){
return ((num&0x55555555)<<1)^((num&0xaaaaaaaa)>>1);
}