移位运算符

Java 有三种移位运算,即>>(算术右移)>>>(逻辑右移)<<(逻辑左移),对应的操作是:

>>

算术右移,将当前操作数的二进制形式顺位右移某几位,并保持最高位与移动前一致,其余位补 0。

>>>

逻辑右移,将当前操作数的二进制形式顺位右移某几位,其余位补 0。

<<

左移,将当前操作数的二进制形式顺位左移某几位,其余位补 0 。

左操作数

移位运算可以对short int byte char long等数使用,但是使用的时候所做的操作不尽相同。

Int

一个 int 类型的移位运算,是对一个 32 位的二进制进行移位,如4 >> 2 ⇔ 0000 0000 0000 0000 0000 0000 0000 0100 >> 2 ⇔ 0000 0000 0000 0000 0000 0000 0000 0001,而-4 >> 2 ⇔ 1111 1111 1111 1111 1111 1111 1111 1100 >> 2 ⇔ 1111 1111 1111 1111 1111 1111 1111 1111,同时-4 >>> 2 ⇔ 1111 1111 1111 1111 1111 1111 1111 1100 >> 2 ⇔ 0011 1111 1111 1111 1111 1111 1111 1111,算数移位与逻辑移位的效果可见一斑。

Long

对于一个 long 类型的移位,是对一个 64 位的操作数进行移位,与 int 类似。

Short Byte Char

对于这些类型的移位操作,一般都是先转化为 Int 类型然后进行移位,移位之后再将 int 类型转化为原本的类型之后输出。

右操作数

移位运算对右操作数也是有一定规则的,如对一个 int 类型的左操作数来说,其右操作数只有低 5 位有效,因为对一个 int 类型,只有 32 位的数字来说,最多也就是只能位移 32 位,也就是11111B位,所以其右操作数 5 位刚刚好。那么对于 long 类型的数来说,右操作数也就低 6 位有效,同理。

移位与乘法

由移位的逻辑可知,算术右移1位与除以2相同,左移1位与乘以2结果相同,所以在写代码的过程中经常使用移位运算来代替乘法运算以提升代码的运行效率。因为数据在计算机内部是以二进制的方式存放的,那么直接使用二进制运算必然能够更快一些,另一方面,移位运算,究其原理就是通过移动 + 补全的操作完成的一个运算,但是乘法运算是通过 ALU 运算器(一系列的加法转换完成的),相比之下确实是移位更具有优势,但是具有优势必然具有缺陷,移位只能对特定范围内的数、特定的乘法运算使用。

至于使用移位还是使用乘法,其实一般情况下却是很难体现移位相对于乘法的优势,除非一段程序中有大量的需要乘法操作的时候,大部分情况下还是会为了程序的易读性,直接使用乘除法。