在各种源码中,都会存在位运算的操作,总是不晓得它的意思,抽时间整理一下,在了解位操作运算符之前,需要能了解10进制和2进制之间如何转换;
十进制和二进制
十进制转二进制
无符号转换
例如将10转换为二进制就是0000 0000 0000 0000 0000 0000 0000 1010
,原理如图:
不断将十进制数除以2,直至最后的值为0,然后将每步的余数按照箭头方向从高位到低位组合得到1010,但是int类型在java中是32位,所以需要将前面补0,最后则为0000 0000 0000 0000 0000 0000 0000 1010
;
ps : 为什么是32位,因为int类型占4个字节,32位,首位为符号位,0 表示正数,1表示负数。
有符号转换
上面是属于无符号之间的转换,若是-10的话,需要得到10的二进制数后,得到-10的原码,然后取原码的反码,最后+1后得到补码,具体操作:
上面提到二进制首位为符号位,负数的首位应该为1,得到-10 的原码为:
1000 0000 0000 0000 0000 0000 0000 1010
;
反码则是将除首位以外的数字取反,即将0变1,1变0,即为:
1111 1111 1111 1111 1111 1111 1111 0101
;
ps : 需要注意的是,正数的反码与原码相同;
将反码+1得到补码,为:
1111 1111 1111 1111 1111 1111 1111 0110
;
通过计算器验证:
二进制转十进制
无符号转换
将 二进制数0000 0000 0000 0000 0000 0000 0000 1010
转换位十进制计算过程如下:
从末位开始逐步计算
0
∗
2
0
+
1
∗
2
1
+
0
∗
2
2
+
1
∗
2
3
=
10
0*2^0+1*2^1+0*2^2+1*2^3 = 10
0∗20+1∗21+0∗22+1∗23=10
有符号转换
将1111 1111 1111 1111 1111 1111 1111 0110
转化为十进制计算过程如下:
根据十进制转二进制有符号转换公式可知,需要将 1111 1111 1111 1111 1111 1111 1111 0110
进行-1处理得到 1111 1111 1111 1111 1111 1111 1111 0101
,然后再取反得到 0000 0000 0000 0000 0000 0000 0000 1010
,再通过计算最终得到10,由于二进制首位是1,所以结果是-10;
位操作运算
Java 定义了位运算符,应用于整数类型 (int
),长整型 (long
),短整型 (short
),字符型 (char
),和字节型 (byte
) 等类型。位运算时先转换为二进制,再按位运算。
主要的位运算操作符
&
按位与|
按位或^
按位异或~
按位补<<
按位左移>>
有符号按位右移>>>
无符号按位右移(高位只补0)
以下操作均定义 int a = 3 , b = 4 , c 为计算出的结果。其中a和b转换为二进制(高位省略)的值:0000 0011
和0000 0100
;
&
操作符
与操作,两个二进制数相同位上如果都是1,则结果为1,否则为0;
得到的最终结果为0;
|
操作符
或操作,两个二进制数相同位上如果都是0,则结果为0,否则为1;
得到的最终结果转化为十进制为 7;
^
操作符
异或操作,两个二进制数相同位上如果相同,则结果为0,否则为1;
得到最终结果转化为十进制为7;
~
操作符
按位补 ,翻转操作数的每一位,即 0 变成 1,1 变成 0。
若将a进行~a
后
通过计算得知 ~a的值转化为十进制为-4
<<
操作符
左移位 表达式为 a << b
,即为将 a 左移 b位,低位补0,抛弃高位。
>>
操作符
带符号右移位 表达式为 a >> b
,即为将 a 右移 b位,抛弃低位,若为负数高位补1,若为正数高位补0;
>>>
操作符
无符号右移位 表达式为 a >> b
,即为将 a 右移 b位,抛弃低位,高位补0;