位运算涉及到的东西还是比较多的
~按位取反 全部取反
代码:
System.out.println(~1);
结果:
代码结果为-2
原理:
要想知道~1首先转化1的原码
上篇博客提到过正数的原码反码和补码是一样的。所以直接将1的原码按位取反,而后得到的是一个负数的补码,再按部就班求出这个原码就得到-2
如下所示:
0000000000000…1 这里是1的原码
1111111111111…0 补码 按位取反后的补码
1111111111111…01 反码 转换后的反码
1000000000000…10 原码 最后的原码-2
为了让大家更好的理解再来一个负数就是-3。
先看一下结果:
-3的编码如下:
原码:100000000000…11
反码:1111111111111…00
补码:1111111111111…01
~3的编码如下:
补码:00000000000…10(这里是-3的补码按位取反的结果)
这里可以看到补码就已经是正数了,正数的原码反码和补码都是一样的。所以结果就是2。
^ 按位异或 2个不相同结果就为1
代码:
System.out.println(-1^-2);
结果:
原理:
-1的所有编码如下:
100000000…0001 原码
111111111…1110 反码
111111111…1111 补码
-2的所有编码如下:
100000000…0010 原码
111111111…1101 反码
111111111…1110 补码
注意所有的运算都是补码的运算,然后再转换为原码
由两数的补码可以看书前面的位数都是相同的所以前面都是0,所以最后的补码是:000000000…0001 补码 = 1
& 按位与 2个都为1结果才为1
代码:
System.out.println(-1&-2);
结果:
原理:
同样的原码反码补码如下:
-1的所有编码如下:
100000000…0001 原码
111111111…1110 反码
111111111…1111 补码
-2的所有编码如下:
100000000…0010 原码
111111111…1101 反码
111111111…1110 补码
由按位&的规则两个都为1结果才为1,所以最后的结果就长这样:
111111111…1110 补码
111111111…1101 反码
100000000…0010 原码 -2
| 按位或 有一个为1结果就为1
代码:
System.out.println(-1|-2);
结果:
原理:
同样的原码反码补码如下:
-1的所有编码如下:
100000000…0001 原码
111111111…1110 反码
111111111…1111 补码
-2的所有编码如下:
100000000…0010 原码
111111111…1101 反码
111111111…1110 补码
按位或的规则:有一个为1结果就为1
111111111…1111 补码
111111111…1110 反码
100000000…0001 原码 -1
移位运算
<< 算术左移 低位补0
代码:
比如1算数左移两位:
System.out.println(1<<2);
结果:
原理:
首先1的补码:000000000…1
左边移动两位:00000000…100 =4
如果是-1算数左移两位呢?
先来看结果:
-1的所有编码如下:
100000000…0001 原码
111111111…1110 反码
111111111…1111 补码
左移后结果如下:
111111111…1100 补码
111111111…1011 反码
100000000…0100 原码 = -4
>> 算术右移 高位补符号位
代码:
System.out.println(1>>2);
结果:
原理:
其实这里不难理解
1的补码:000000000…1
结果补码: 000000000…0 = 0
这里首先右移两位那么1就没有了,而后补符号位,符号位也是0所以最后结果是0。
而后再看-1的右移运算。先看结果:
而后,-1的所有编码如下:
100000000…0001 原码
111111111…1110 反码
111111111…1111 补码
而后补码右移,首先右移以后全部都是1,再补符号位,符号位也是1。
所以结果是111111111…1111 补码 =-1
最后再来看一个:
>>> 逻辑右移 高位补0
代码:
System.out.println(1>>>2);
结果:
原理:
1 >>>2
000000000…1 这里是1的补码
000000000…0 =0 逻辑右移,高位补0
再来看一个负数
-1>>>2
直接看结果,这一次结果就比较大了:
100000000…0001 原码
111111111…1110 反码
111111111…1111 补码
00111111111111 补码 高位补0以后的结果1073741823