一、异或运算^
1、基本特性
(1)0^0=0 , 1^0=1 任何数异或0 不变
(2)0^1=1 , 1^1=0 任何数异或1 取反 , 如果想将某一个位反转,只需异或1就行
(3)任何数异或自己 变成0
(4)异或满足交换律
2、使用异或的案例
(1)交换两个数不需要使用额外空间:自己异或自己为0,任何数异或0不变,异或满足交换律
两个数A,B。通过如下方法实现交换A,B:
A = A ^ B; B = B ^ A; A = A ^ B;
(2)一个整形数组,其中所有的数都出现了两次,除了有两个数只出现一次之外。如何在最短的时间内获取到这两个数。
二、移位运算
在移位运算时,byte、short和char类型移位后的结果会变成int类型,对于byte、short、char和int进行移位时,规定实际移动的次数是移动次数和32的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和64的余数,也就是移动66次和移动2次得到的结果相同。如下:
16>>34和16>>2 结果相同
16>>32 结果还是16
1、右移(>>):移动时低位舍弃
(1) 正数右移时,高位补0
(2)负数右移时,符号位不变:1,右移后空出来的高位全补1
如 -16>>2 = -4
-16 原码:1000 0000 0000 0000 0000 0000 0001 0000
-16 反码:1111 1111 1111 1111 1111 1111 1110 1111
-16 补码:1111 1111 1111 1111 1111 1111 1111 0000(反码加1)
右移2位: 1111 1111 1111 1111 1111 1111 1111 1100(补码)
转换为原码: 1000 0000 0000 0000 0000 0000 0000 0100 (结果为-4)
2、>>> 无符号右移:不管正负数,带符号移动后,空出来的高位补0
-16>>>2 = 1073741820
-16 补码:1111 1111 1111 1111 1111 1111 1111 0000
无符号右移2位: 0011 1111 1111 1111 1111 1111 1111 1100(补码,由于符号位为0,为正数)
结果为: 1073741820 //使用Integer.toBinaryString(1073741820)可以验证
3、左移(<<):按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零
左移的规则只记住一点:丢弃最高位(符号位同样丢弃),0补最低位 (由于是负数,补码左移后结果还是负数)
-16<<2 = -64