java 位运算符详解
一、概述
-
Java 定义的位运算(bitwise operators)直接对整数类型的位进行操作,这些整数类型包括 long,int,short,char 和 byte。
-
位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位(bit)进行计算,其操作数和运算结果都是整型值。
-
Java 语言中的位运算符分为位逻辑运算符和位移运算符两类,下面详细介绍每类包含的运算符。
二、位逻辑运算符
运算符 | 含义 | 实例 | 结果 |
---|---|---|---|
& | 按位进行与运算(AND) | 4 & 5 | 4 |
| | 按位进行或运算(OR) | 4 | 5 | 5 |
^ | 按位进行异或运算(XOR) | 4 ^ 5 | 1 |
~ | 按位进行取反运算(NOT) | ~ 4 | -5 |
2.1 位与运算符: &
运算规则:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位同时为 1,那么计算结果才为 1,否则为 0。因此,任何数与 0 进行按位与运算,其结果都为 0。
以 100 & 0 为例:
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 为例:
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为例:
System.out.print("位异或运算: " + "整型");
System.out.println( 11^7 );
System.out.println("整型转为二进制:" + Integer.toBinaryString(11^7) );
运行结果:
位异或运算: 整型:12
整型转为二进制:1100
提示:在有的高级语言中,将运算符^
作为求幂运算符,要注意区分。
2.4 位取反运算符: ~
运算规则:只对一个操作数进行运算,将操作数二进制中的 1 改为 0,0 改为 1。
以~10为例
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 位的过程如下图 所示。
从上图中可以看到,原来数的所有二进制位都向左移动 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 位的过程如下图所示。
从上图 中可以看到,原来数的所有二进制位都向右移动 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
如果有错,欢迎留言指正,一起交流学习,一起进步!