前提:计算机内负数用补码表示;Integer.toBinaryString()会把数据转为整型显示。
相同点:两者都是无符号右移
不同点:>>>长度小于int的,先补齐到int长度,然后位移,高位补0。
>>>=,先按>>>位移然后赋值,但因为重新赋值需要转换数据类型丢失高位数据,导致结果不符合预期。
以byte为例,先看一段代码
byte b = -1;
System.out.println(Integer.toBinaryString(b));
System.out.println(b>>>10);
System.out.println(Integer.toBinaryString(b>>>10));
b >>>= 10;
System.out.println(b);
System.out.println(Integer.toBinaryString(b));
结果:
11111111111111111111111111111111
4194303
1111111111111111111111
-1
11111111111111111111111111111111
解析:byte的-1转为整型, 原码1111 1111 1111 1111 1111 1111 1000 0001
反码1111 1111 1111 1111 1111 1111 1111 1110
补码1111 1111 1111 1111 1111 1111 1111 1111
b>>>10 补码右移10位(去掉右侧10位)左侧补0,得到
0000 0000 0011 1111 1111 1111 1111 1111(4194303)
b >>>=10 ,先执行-1>>>10得到上面的结果,再转为byte,原来结果是4194303,再转为byte,byte只有8个二进制位,所以左侧长度大于8的部分全部丢失得到低8位1111 1111 ,
除符号位外按位取反得到 1000 0000,上述结果+1得原码:1000 0001 即-1。例子中最后一行byte类型的-1因为调用了Integer.toBinaryString()又被转为了整型-1输出32位。
总结:byte、short的负数进行>>>操作直接操作即可不需要重新赋值,否则会得到错误结果。