Java移位运算

JAVA 中有以上三种移位符号,那么下面的输出是什么呢?

System.out.println(0xff >>> 7);

System.out.println((((byte) 0xff) >>> 7));

System.out.println((byte) (((byte) 0xff) >>> 7));

1、三种移位符号的意义是什么?

>> 是带符号右移,若左操作数是正数,则高位补“0”,若左操作数是负数,则高位补“1”.
<< 将左操作数向左边移动,并且在低位补0.
>>> 是无符号右移,无论左操作数是正数还是负数,在高位都补“0”

2、三种移位符号作用的左操作数有五种:long,int,short,byte,char,但是在作用不同的操作数类型时,其具体过程不同, 遵循一下几个原则:

a : int移位时,左边的操作数是32位的,此时的移位符号作用在32位bit上。如:1 >> 3, 是将00000000 00000000 00000000 00000001这32位向右边移动3位。

b: long 移位时,左边的操作数是64位的,此时移位符号作用在64位bit上。如:1L >> 3。

c: short, byte,char 在移位之前首先将数据转换为int,然后再移位,此时移位符号作用在32为bit上。如:(byte)0xff >>> 7, 是将11111111 11111111 11111111 11111111向右边移动7位,得到00000001 11111111 11111111 11111111, 所以结果不是你所期望的1,呵呵。

3、有1,2可知,当左操作数是long时,移位之后得到的类型是long,当左操作数是其它四中类型时,移位之后得到的类型是int,所以如果做操作数是byte,char,short 时,你用 >>=,>>>=, <<= 其实是将得到的int 做低位截取得到的数值。这里往往容易犯错。

4、三种移位符号除了对做操作数有操作规则外,其实对右操作数也有操作规则。如果左操作数(转换之后的)是int,那么右操作数只有低5位有效,为什么?因为int 总共就32位,如:23 >> 33, 结果与23 >>1是一样的,都是11;同理,如果左边操作数是long,那么右边操作数只有低6位有效。

System.out.println(0xff >>> 7);

0xff 本身就是一个int,其bits为:00000000 00000000 00000000 11111111,无符号向右移动7位, 得到的bits当然为:00000000 00000000 00000000 00000001,

System.out.println((((byte) 0xff) >>> 7));

(byte)0xff 是一个byte,bits为: 11111111, 首先转换为int,其bits为:11111111 11111111 11111111 11111111, 向右边无符号移动7为,得到的结果bits是:00000001 11111111 11111111 11111111。

System.out.println((byte) (((byte) 0xff) >>> 7));

(byte) 0xff 是一个byte,bits为: 11111111, 首先转换为int,其bits为:11111111 11111111 11111111 11111111,向右边无符号移动7为,得到的结果bits是:00000001 11111111 11111111 11111111,然后转换为byte,低位截取得到bits: 11111111, 在输出的时候转换为int, 其bits为:11111111 11111111 11111111 11111111.

上面三个的结果是:

1
33554431
-1