在平时看各种框架的源码的过程中,经常会看到一些位移运算,所以作为一个Java开发者是一定掌握位移运算的@mikechen
为什么要使用位运算?
在计算机中所有数据都是以二进制的形式储存的,位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快。
位运算是最贴近计算机真实运算操作,通过位运算,我们可以高效的完成各种基础运算(加减乘除取余等),我们还可以使用位运算巧妙的完成原本很复杂的工作。
Java中的位运算符
位运算符主要针对二进制,很多编程语言都有位运算符,Java语言也不例外。
在Java语言中,提供了7种位运算符,分别是:
- 按位与(&)
- 按位或(|)
- 按位异或(^)
- 取反(~)
- 左移(<<)
- 带符号右移(>>)
- 无符号右移(>>>)
这些运算符当中,仅有~是单目运算符,其他运算符均为双目运算符。
在讲解这些运算符的使用之前,必须了解一个常识,那就是:位运算符是对long、int、short、byte和char这5种类型的数据进行运算的,我们不能对double、float和boolean进行位运算操作,下面就来详细讲解这7种位运算符的使用方法。
按位与(&)
按位与运算符的写法是一个”&”符号,表示如果两个输入位都是1,那么按位“与”(&)操作就会生成一个输出位1,否则生成一个输出位0,如下图所示:
按位或(|)
或运算符用符号“|”表示,其运算规律如下:
只要对应的两个二进制位有一个为1,结果就为1,否则就为0,如下图所示:
按位异或(^)
异或运算符是用符号“^”表示的,其运算规律是:
两个操作数的位中,位相同则结果为0,不同则结果为1,如下图所示:
取反(~)
按位非(~)操作符,也称为取反操作符,它属于一元操作符。
只对一个数进行操作(其他按位操作符是二元操作符),按位“非”生成与输入位相反的值,若输入0,则输出1;若输入1,则输出0。
我们以数字5为例讲解按位取反的运算过程,如下图所示:
首先把数字5转换成补码形式,之后把每个二进制位上的数字进行取反,如果是0就变成1,如果1就变成0。
左移(<<)
左移运算符用“<<”表示,是将运算符左边的对象,向左移动运算符右边指定的位数,并且在低位补零。
其实,向左移n 位,就相当于乘上2 的n 次方,例如下面的例子。
public static void main(String[] args) { int a=2; int b=2; System.out.println("a 移位的结果是:"+(a<<b)); }
运行结果:a 移位的结果是:8
分析上面的程序段:
首先从本质上来分析,2 的二进制是00000010,它向左移动2 位,就变成了00001000,即8。
如果从另一个角度来分析,它向左移动2 位,其实就是乘上2 的2 次方,结果还是8。
带符号右移(>>)
右移运算分为两种,分别是带符号右移和无符号右移,首先我们来说说带符号右移运算符。
带符号的右移运算符用符号“>>”表示,是将运算符左边的运算对象,向右移动运算符右边指定的位数。如果是正数,在高位补零,如果是负数,则在高位补1,先看下面一个简单的例子。
public static void main(String[] args) { int a=16; int c=-16; int b=2; int d=2; System.out.println("a 的移位结果:"+(a>>b)); System.out.println("c 的移位结果:"+(c>>d)); }
运行结果:
a 的移位结果:4
c 的移位结果:-4
分析上面的程序段:
a 的值是16,转换成二进制是00010000,让它右移两位成00000100 即4。
c 的值是-16,转换成二进制是11101111,让它右移一位成11111011 即-4。
无符号右移(>>>)
上面说了右移运算分为两种,分别是带符号右移和无符号右移,现在再来讲解无符号右移。
无符号右移运算符的写法是”>>>”,比带符号右移多了一个”>”。
右移运算符用符号“>>>”表示,是将运算符左边的对象向右移动运算符右边指定的位数,并且在高位补0,其实右移n 位,就相当于除上2 的n 次方。
public static void main(String[] args) { int a=16; int b=2; System.out.println("a 移位的结果是:"+(a>>>b)); }
运行结果
a 移位的结果是:4
分析上面的程序段:从本质上来分析,16 的二进制是00010000,它向右移动2 位,就变成了00000100,即4。
如果从另一个角度来分析,它向右移动2 位,其实就是除以2 的2 次方,结果还是4。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》