Java 位运算

先预知识:

  数据在计算机中是以二进制的形式进行存储的,而二进制在内存中是以补码的形式进行存储的。在介绍位运算之前,首先来看一下原码、反码和补码的概念。由于正数的原码、反码和补码的形式都是一样的,所以以下主要针对负数进行讲解。
  原码:在数值前直接加一符号位的表示法。
  反码:原码的数值位取反(0变1,1变0)。
  补码:原码加1。

  PS:已知补码,求原码。
  分析:按照求负数补码的逆过程,可以采取补码减1再取反的思路。但是对于二进制来说,减1取反和取反加1的效果是一样的。所以仍然可以采用取反加1的方法来求得原码。

Java中的位运算符有:&(按位与)、|(按位或)、^(按位异或)、~(取反)、<<(左移)、>>(右移)、>>>(无符号右移)。

以int型数据为例介绍,占4个字节,32位:(以下1代表true,0代表false)
&(按位与):当两边操作数全为true时返回true,否则返回false

如,6&3=2,看步骤:
6 00000000 00000000 00000000 00000110
3 00000000 00000000 00000000 00000011
& -------------------------------------------------------
2 00000000 00000000 00000000 00000010

-6&3=2,看步骤:
-6 11111111 11111111 11111111 11111010(补码,原码取反再加1)
3  00000000 00000000 00000000 00000011
& ---------------------------------------------------------
2  00000000 00000000 00000000 00000010

 

|(按位或):两边操作数只要有一边为true,结果就为true,只有当两边操作数全为false时才返回false

如,6|3=7,看步骤:
6 00000000 00000000 00000000 00000110
3 00000000 00000000 00000000 00000011
| ---------------------------------------------------------
7 00000000 00000000 00000000 00000111

-6|3=-5,看步骤:
-6 11111111 11111111 11111111 11111010(补码,原码取反再加1)
3  00000000 00000000 00000000 00000011
| ----------------------------------------------------------
-5 10000000 00000000 00000000 00000101(原码,补码取反再加1)

 

^(按位异或):两边操作数相同就为false,不同则为true

如,6^3=5,看步骤:
6 00000000 00000000 00000000 00000110
3 00000000 00000000 00000000 00000011
^ ---------------------------------------------------------
5 00000000 00000000 00000000 00000101

-6^3=-7,看步骤:
-6 11111111 11111111 11111111 11111010(补码,原码取反再加1)
3  00000000 00000000 00000000 00000011
^ ---------------------------------------------------------
-7 10000000 00000000 00000000 00000111(原码,补码取反再加1)

 

~(取反):二进制每一位取反,1变0,0变1

如:~6=-7,看步骤:
6  00000000 00000000 00000000 00000110
~ --------------------------------------------------------
-7 10000000 00000000 00000000 00000111(原码,补码取反再加1)

~(-6)=5,看步骤:
-6 11111111 11111111 11111111 11111010(补码,原码取反再加1)
~ --------------------------------------------------------
5  00000000 00000000 00000000 00000101

 

<<(左移):所有位向左移动一位,相当于乘以2,低位用0补齐

如:6<<1=12,看步骤:
6     00000000 00000000 00000000 00000110
<< -----------------------------------------------------------
12 000000000 00000000 00000000 00001100

如:-6<<1=-12,看步骤:
-6     11111111 11111111 11111111 11111010(补码,原码取反再加1)
<< ----------------------------------------------------------
-12 100000000 00000000 00000000 00001100(原码,补码取反再加1)

 

>>(右移):所有位向右移动一位,相当于除以2,高位按符号位补齐

如:6>>1=3,看步骤:
6   00000000 00000000 00000000 00000110
>> ---------------------------------------------------------
3   00000000 00000000 00000000 000000110

-6>>1=-3,看步骤:
-6 11111111 11111111 11111111 11111010(补码,原码取反再加1)
>> ---------------------------------------------------------
-3 10000000 00000000 00000000 000000110

 

>>>(无符号右移):所有位向右移动一位,相当于除以2,高位用0补齐

如:6>>1=3,看步骤:
6      00000000 00000000 00000000 00000110
>>> ---------------------------------------------------------
3    00000000 00000000 00000000 000000110

-6>>>1=2147483645,看步骤:
-6   11111111 11111111 11111111 11111010(补码,原码取反再加1)
>>> -----------------------------------------------------------------
2147483645 01111111 11111111 11111111 111111010

 
 
 
posted @ 2019-08-02 13:52  panda4j  阅读(79)  评论(0)    收藏  举报