今天主要了解一下按位操作符和移位操作符,因为看源码的时候经常会遇到,之前有点不明白,趁着这次机会学习一下。
### 按位操作符
按位操作符是用来操作整数基本类型中的当个“比特”,即二进制位。
#### 与操作符 &
如果两个输入位都是1,则会生成一个输出位1;否则会生成一个输出位0。
举个例子:
```
13: 1101
6: 0110
13 & 6 得到 0100 --> 4
```
#### 或操作符 |
如果两个输入为只要有一个是1,则生成一个输出位1;只有两个输入位都为0的情况下才会生成一个输出位0。
例如:
```
12: 1100
6: 0110
12 | 6 得到 1110 --> 14
```
#### 异或操作 ^
如果两个输入位中的某一个是1,但不全是1,按照异或操作会生成一个输出位1。
如果两个输入位都是1或者都是0,则生成一个输出位0。
例如:
```
12: 1100
6: 0110
12 ^ 6 得到 1010 --> 10
```
#### 按位非 ~
按位非也叫取反操作符,属于一元操作符,只针对一个操作数进行操作(前面几个操作符都是针对两个操作数,叫做二元操作符),它的主要操作是如果输入0,则输出1;如果输入1,则输出0。
>6的二进制为:
00000000000000000000000000000110
对每一位都进行取反,得到:
11111111111111111111111111111001
这是内存中的保存形式。
我们读取的十进制是根据原码来读取,而在内存中,数值都是以二进制补码形式保存的。
正数的补码和原码一样,负数的原码转补码或者补码转原码的规则:
符号位不变,将剩余位取反,得到反码,在反码的基础上最后一位加一得到负数的补码。
>
>11111111111111111111111111111001 输出10进制的过程:
1.符号位不变,剩余位取反
10000000000000000000000000000110
2.最后一位加1
10000000000000000000000000000111
```
System.out.println(Integer.toBinaryString(6));
System.out.println(~6);
System.out.println(Integer.toBinaryString(~6));
```

对任一数值 x 进行按位非操作 ~x = -(x + 1)。例如,~6 结果为 -7。
### 移位操作符
移位操作符操作的对象也是二进制的“位”。移位操作符只能用来操作整数类型。
#### 左移位操作符 <<
左移位操作符能按照右侧指定的位数将操作符左边的操作数向左移动,在低位补0。
>十进制中1的进制表示为:
0000 0001
当执行 1 << 4,将其向左移动4位,得到:
0001 0000
换算位十进制就是16
#### 右移位操作符 >>
右移位操作符按照操作符右侧指定的位数将操作符左边的操作数向右移动。
右移操作符使用“符号扩展”,主要表现为:
(1)如果符号为正,则在高位插入0;
(2)如果符号为负,则在高位插入1;
还有一种无符号的右移位操作符 >>> ,使用零扩展,无论正负,都在高位插入0。
>25的二进制为:
00011001
当执行 25 >> 2,将其向右移动2位,得到:
00000110
换算位十进制就是6
>下面看下无符号的有移位,-25的二进制表示为:
11111111111111111111111111100111
当执行 25 >> 2,将其向右移动2位,得到:
00111111111111111111111111111001
换算位十进制就是 1073741817

按位操作符和移位操作符