移位、位与、或、异或、非

Java位运算符有:左移( << )、右移( >> ) 、无符号右移( >>> ) 、位与( & ) 、位或( | )、位非( ~ )、位异或( ^ ),除了位非( ~ )是一元操作符外,其它的都是二元操作符。

原码、反码、补码

原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。

00000000 00000000 00000000 00000101   是5的原码

反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。即:1变0; 0变1

11111111 11111111 11111111 11111010   是5的反码

补码:反码加1称为补码。

11111111 11111111 11111111 11111011   是5的补码

在学习位移之前,我们先了解负数二进制的表示,你可能听过两种不同的回答。

一种是教科书,它会告诉你:计算机用“补码”表示负数。例如上面5的补码:11111111 11111111 11111111 11111011表示-5

另一种是一些程序员告诉你的:用二进制数的最高位表示符号,最高位是0,表示正数,最高位是1,表示负数。这种说法本身没错,可是如果没有下文,那么它就是错的。至少它不能解释,为什么字符类型的-1用二进制表示是“1111 1111”(16进制为FF);而不是我们更能理解的“1000 0001”。(为什么说后者更好理解呢?因为既然说最高位是1时表示负数,那1000 0001不是正好是-1吗?

其实对于计算机来说没有正负二进制之分,比如一个8位的二进制1111 1001,即可以表示-7,也可以表示249,最终得到的结果是正是负取决于开发者本人如何定义这个变量(数据的类型,比如int,unsigned,long,double等等),如果你定义的是一个负值,则补码先减1得到反码1111 1000,然后反码取反得到原码0000 0111,原码转换二进制为7,由于你定义的是一个负数则添加负号得到-7返回

左移(<<)

先看一个例子:5左移2位

public class DisplacementOperatorTest {
    public static void main(String[] args) {
        // 5左移2位的结果为20
        System.out.println(5 << 2);
    }
}

下面是具体操作过程(Java整数默认int类型,二进制为32位):

5的二进制:
0000 0000 0000 0000 0000 0000 0000 0101

左移2位,低位补0后,得到:
0000 0000 0000 0000 0000 0000 0001 0100

换算成10进制为:20

右移(>>)

先看一个例子:5右移2位

public class DisplacementOperatorTest {
    public static void main(String[] args) {
        // 5右移2位的结果为1
        System.out.println(5 >> 2);
    }
}

下面是具体操作过程(Java整数默认int类型,二进制为32位):

5的二进制:
0000 0000 0000 0000 0000 0000 0000 0101

右移2位,高位补0后,得到:
0000 0000 0000 0000 0000 0000 0000 0001

换算成10进制为:1

无符号右移(>>>)

  • 正数右移,高位补0
  • 正数左移,低位补0
  • 负数右移,高位补1
  • 负数左移,低位补0
  • 负数无符号右移,高位补0
  • 负数没有无符号左移

先看一个例子:

public class DisplacementOperatorTest {
    public static void main(String[] args) {
        //结果是0
        System.out.println(5 >> 3);

        //结果是-1
        System.out.println(-5 >> 3);

        //结果是536870911
        System.out.println(-5 >>> 3);
    }
}

下面是具体操作过程(Java整数默认int类型,二进制为32位):

5的二进制:
0000 0000 0000 0000 0000 0000 0000 0101

5右移3位,高位补0后,换算成十进制得0:
0000 0000 0000 0000 0000 0000 0000 0000

-5得二进制:
1111 1111 1111 1111 1111 1111 1111 1011

-5右移3位,高位补1后,换算成十进制得-1
1111 1111 1111 1111 1111 1111 1111 1111

-5无符号右移3位,高位补0后,换算成十进制得536870911

位与(&)

第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0

5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

1转换为二进制:0000 0000 0000 0000 0000 0000 0000 0001

位或(|)

第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0

5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

7转换为二进制:0000 0000 0000 0000 0000 0000 0000 0111

异或(^)

第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n为也为1,否则为0

5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

6转换为二进制:0000 0000 0000 0000 0000 0000 0000 0110

位非(~)

操作数的第n位为1,那么结果的第n位为0,反之

5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101

-6转换为二进制:1111 1111 1111 1111 1111 1111 1111 1010
posted @ 2020-02-03 12:26  KeSuns  阅读(647)  评论(0编辑  收藏  举报