位运算
位与 & = 真真为真,真假为假,假假为假
位或 | = 真真为真,真假为真,假假为假,有一个真为真
位非 ~ = 取反码
位异或^ = 真真为假,真假为真,假假为假,相同则为假
判断一个数的奇偶
#true奇数 false偶数
boolean OddNumber = (n&1) == 1;
判断奇偶数,只需要判断最后一位二进制是不是1。
如果二进制最后一位是1,代表是奇数。
如果二进制最后一位是0,代表是偶数。
不用中间变量,交换2个值
第一个方法:
int a = 10;
int b = 20;
a = a + b; //a=10+20=30; a等于20
b = a - b; //b=20-10=10; b已经交换
a = a - b; //a=30-10=20; a已经交换
第二个方法(推荐,效率高):
int a = 10; //10的二进制=01010
int b = 20; //20的二进制=10100
a = a ^ b; //【1】
b = a ^ b; //【2】
a = a ^ b; //【3】
^异或运算法则:
x^x=0 //如果两个值相同,异或结果为0
0^0=0
x^0=x //
把【1】代入【2】中得到:b = (a ^ b) ^ b = a ^ 0 = a //这里就把a的值赋给了b;
把【2】代入【3】中得到:a = (a ) ^ (a ^ b) = b //这里就把b的值赋给了a;
第一步:a = a ^ b; //【1】
01010
10100
a=11110 //这里步其实可以的得到a的二进制=11110,10进制为30
第二步:b = a ^ b; //【2】
11110 //将第一步a的结果代入
10100
b=01010 //这里步其实可以的得到b的二进制=01010,10进制为10,这里就已经发生互换
第三步:b = a ^ b; //【3】
11110 //将第一步a的结果代入
01010 //将第二步b的结果代入
a=10100 //这里步其实可以的得到a的二进制=10100,10进制为20,这里就已经发生互换
找出没有重复的数字或字母
给定一个**非空**整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。
找出那个只出现了一次的元素。
^异或根据这个规律:
x^x=0
x^0=x
如果数据是成对出现,相当于会消除掉。所有数据全部异或一下,剩下那个就是需要找的数字
class Solution {
public int singleNumber(int[] nums) {
int result=0;
for(int num:nums){
result = result ^ num;
}
return result;
}
}
左移一位,相当于乘以2的运算
int num = n<<1;
比如num=10, 二进制是 1010
左移一位相当于二进制为 10100=20,//左移一位相当于*2
左移两位相当于二进制为101000=40,//左移一位相当于*2*2,即乘4
@Test
public void testLeft() {
int positive = 100;
int positiv_left_one = positive << 1;
int positiv_left_two = positive << 2;
log.info("正式positive={},左移一位={},左移两位={}", positive, positiv_left_one, positiv_left_two);
int negative = -100;
int negative_left_one = negative << 1;
int negative_left_two = negative << 2;
log.info("负数negative={},左移一位={},左移两位={}", negative, negative_left_one, negative_left_two);
}
10:11:01.138 [main] INFO 位运算.TestBinary - 正式positive=100,左移一位=200,左移两位=400
10:11:01.144 [main] INFO 位运算.TestBinary - 负数negative=-100,左移一位=-200,左移两位=-400
右移一位,相当于除以2的运算
@Test
public void testRight() {
int positive = 100;
int positiv_right_one = positive >> 1;
int positiv_right_two = positive >> 2;
log.info("正式positive={},右移一位={},右移两位={}", positive, positiv_right_one, positiv_right_two);
int negative = -100;
int negative_right_one = negative >> 1;
int negative_right_two = negative >> 2;
log.info("负数negative={},右移一位={},右移两位={}", negative, negative_right_one, negative_right_two);
}
11:22:18.113 [main] INFO 位运算.TestBinary - 正式positive=100,右移一位=50,右移两位=25
11:22:18.120 [main] INFO 位运算.TestBinary - 负数negative=-100,右移一位=-50,右移两位=-25
\TeX
x^2^
二进制转10进制
214的二进制= 1 1 0 1 0 1 1 0
(从右边往左计算2的几次方,从0次方开始)
= 1* + 1* + 0* + 1* + 0* + 1*+ 1*+ 0*
= 128 + 64 + 0 + 16 + 0 + 4 + 2 + 0
= 214
按位与&
位与 & = 真真为真,真假为假,假假为假
| & | & | & | & | |
|---|---|---|---|---|
| 第一个数 | 0 | 0 | 1 | 1 |
| 第二个数 | 1 | 0 | 0 | 1 |
| 结果 | 0 | 0 | 0 | 1 |
位或 |
位或 | = 真真为真,真假为真,假假为假,有一个真为真
| | | | | | | | | |
|---|---|---|---|---|
| 第一个数 | 0 | 0 | 1 | 1 |
| 第二个数 | 1 | 0 | 0 | 1 |
| 结果 | 1 | 0 | 1 | 1 |
位非 ~
位非 ~ = 取反码
| ~ | ~ | |
|---|---|---|
| 操作数 | 0 | 0 |
| 结果 | 1 | 1 |
位异或^
位异或^ = 真真为假,真假为真,假假为假,相同则为假
| ^ | ^ | ^ | ^ | |
|---|---|---|---|---|
| 第一个数 | 0 | 0 | 1 | 1 |
| 第二个数 | 1 | 0 | 0 | 1 |
| 结果 | 1 | 0 | 1 | 0 |