java 位运算符详解

java 位运算符

一、概述

  • Java 定义的位运算(bitwise operators)直接对整数类型的位进行操作,这些整数类型包括 long,int,short,char 和 byte。

  • 位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位(bit)进行计算,其操作数和运算结果都是整型值。

  • Java 语言中的位运算符分为位逻辑运算符和位移运算符两类,下面详细介绍每类包含的运算符。

二、位逻辑运算符

位逻辑运算符包含 4 个:&(与)、|(或)、~(非)和 ^(异或)。除了 ~(即位取反)为单目运算符外,其余都为双目运算符。

表 1 中列出了它们的基本用法。
运算符含义实例结果
& 按位进行与运算(AND) 4 & 5 4
| 按位进行或运算(OR) 4 | 5 5
^ 按位进行异或运算(XOR) 4 ^ 5 1
~ 按位进行取反运算(NOT) ~ 4 -5

2.1 位与运算符: &

运算规则:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位同时为 1,那么计算结果才为 1,否则为 0。因此,任何数与 0 进行按位与运算,其结果都为 0。

以 100 & 0 为例:

img

System.out.print("位与运算:  "  + "整型");
System.out.println( 0&100);
System.out.println("整型转为二进制:" + Integer.toBinaryString(0&100) );
运行结果:
   位与运算:  整型:0
整型转为二进制:0

 


2.2 位或运算符: |

运算规则:参与运算的数字,低位对齐,高位不足的补零。如果对应的二进制位只要有一个为 1,那么结果就为 1;如果对应的二进制位都为 0,结果才为 0。

下面以11 | 7 为例:

img

System.out.print("位或运算:  "  + "整型");
System.out.println( 11|7 );
System.out.println("整型转为二进制:" + Integer.toBinaryString(11|7) );
运行结果:
位或运算:  整型:15
整型转为二进制:1111

 


 

2.3 异或运算符: ^

运算规则:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位相同(同时为 0 或同时为 1)时,结果为 0;如果对应的二进制位不相同,结果则为 1。

以 11^7为例

img

        System.out.print("位异或运算:  "  + "整型");
       System.out.println( 11^7 );
       System.out.println("整型转为二进制:" + Integer.toBinaryString(11^7) );
运行结果:
   位异或运算:  整型:12
整型转为二进制:1100

 

提示:在有的高级语言中,将运算符^作为求幂运算符,要注意区分。


2.4 位取反运算符: ~

运算规则:只对一个操作数进行运算,将操作数二进制中的 1 改为 0,0 改为 1。

以~10为例

img

        System.out.print("位取反运算:  "  + "整型");
       int a = ~10;
       System.out.println(a);
       System.out.println("整型转为二进制:" + Integer.toBinaryString(a) );
运行结果:
   位取反运算:  整型:-11
整型转为二进制:11111111111111111111111111110101

 

注意:位运算符的操作数只能是整型或者字符型数据以及它们的变体,不用于 float、double 或者 long 等复杂的数据类型

三、位移运算符

位移运算符用来将操作数向某个方向(向左或者右)移动指定的二进制位数。表 2 列出了 Java 语言中的两个位移运算符,它们都属于双目运算符。

3.1 左位移运算符: <<

运算规则:按二进制形式把所有的数字向左移动对应的位数, 高位移出(舍弃),正负数一样,低位的空位补零。

将整数 11 向左位移 1 位的过程如下图 所示。

img

从上图中可以看到,原来数的所有二进制位都向左移动 1 位。原来位于左边的最高位 0 被移出舍弃,再向尾部追加 0 补位。最终到的结果是 22,相当于原来数的 2 倍

        System.out.print("位左移运算: \n " + "  整型: ");
       System.out.println(2<<1);
       System.out.print(" 二进制: ");
       System.out.println(Integer.toBinaryString(2<<1));
运行结果:
   位左移运算:
     整型: 4
     二进制: 100

 


3.2 右位移运算符: >>

运算规则:按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),如果该数为正数则高位的空位补零,如果为负数,则高位补1。

将整数 11 向右位移 1 位的过程如下图所示。

img

从上图 中可以看到,原来数的所有二进制位都向右移动 1 位。原来位于右边的最低位 1 被移出舍弃,再向最高位追加 0 补位。最终到的结果是 5,相当于原数整除 2 的结果。

        System.out.print("位右移运算: \n " + "  整型: ");
       System.out.println(4>>2);
       System.out.print(" 二进制: ");
       System.out.println(Integer.toBinaryString(4>>2));
运行结果:
   位右移运算:
     整型: 1
     二进制: 1

注意如果该数为正,则高位补0,若为负数,则高位补1;

3.3无符号右位移运算符:>>>

>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0


补充:1、上面讲解的 <<>> 还是 >>> 都是针对补码来进行操作的。因为在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理

2、位运算符和乘2 除2 在大多数时候是很相似的,可以进行替代,同时效率也会高的多,但是两者切记不能混淆 ; 很多时候有人会把两者的概念混淆,尤其是数据刚好是 2、4、6、8等偶数的时候,看起来就更相似了,但是对于奇数,如本文使用的12345 ,右移之后结果为6172 ,这个结果就和数学意义上的除以2不同了,不过对于int 类型的数据,除2 会对结果进行取整,所以结果也是6172 ,这就更有迷惑性了

 

四、复合位赋值运算符

所有的二进制位运算符都有一种将赋值位运算 组合在一起的简写形式。复合位赋值运算符由赋值运算符位逻辑运算符位移运算符组合而成。下表列出了组合后的复合位赋值运算符。

复合位赋值运算符
运算符含义实例结果
&= 按位与赋值 num1 &= num2 等价于 num 1=num 1 & num2
|= 按位或赋值 num1 |= num2 等价于 num 1=num 1 | num2
^= 按位异或赋值 num1 ^= num2 等价于 num 1=num 1 ^ num2
«= 按位左移赋值 num1 «= num2 等价于 num 1=num 1 « num2
»= 按位右移赋值 num1 »= num2 等价于 num 1=num 1 » num2
        //&=
       int a=10,b=5;
       System.out.print("&=: ");
       System.out.println(a&=b);
       //|=
       System.out.print("|=: ");
       System.out.println(a|=b);
       //^=
       System.out.print("^=: ");
       System.out.println(a^=b);
       //>>=
       System.out.print(">>=: ");
       System.out.println(a>>=b);
       //<<=
       System.out.print("<<=: ");
       System.out.println(a<<=b);
运行结果:
   &=0
|=5
^=0
>>=0
<<=0

 

如果有错,欢迎留言指正,一起交流学习,一起进步!

 

 

posted on 2020-05-19 11:25  码出高效,码出未来  阅读(913)  评论(0)    收藏  举报

导航