Java 有 2 个用于右移的位移运算符:
>> shifts right, and is dependant on the sign bit for the sign of the result
>>> shifts right and shifts a zero into leftmost bits
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html
这看起来相当简单,所以任何人都可以向我解释为什么这段代码在为 bar 指定 -128 的值时,为 foo 生成 -2 的值:
byte foo = (byte)((bar & ((byte)-64)) >>> 6);
其目的是获取一个 8 位字节,最左边 2 位的掩码,并将它们移位到最右边的 2 位。 IE:
initial = 0b10000000 (-128)
-64 = 0b11000000
initial & -64 = 0b10000000
0b10000000 >>> 6 = 0b00000010
结果实际上是-2,即
0b11111110
IE。 1 而不是零被移到左侧位置
这是因为 & 实际上是在执行提升int
- 这留下了很多“1”位。然后右移,将最左边的 2 位保留为 0,然后通过转换回字节来忽略这些最左边的位。
当您分离出操作时,这一点会变得更清楚:
public class Test
{
public static void main(String[] args)
{
byte bar = -128;
int tmp = (bar & ((byte)-64)) >>> 6;
byte foo = (byte)tmp;
System.out.println(tmp);
System.out.println(foo);
}
}
prints
67108862
-2
因此,再次进行位算术:
initial = 0b10000000 (-128)
-64 = 0b11000000
initial & -64 = 0b11111111111111111111111110000000 // it's an int now
0b10000000 >>> 6 = 0b00111111111111111111111111100000 // note zero-padding
(byte) (0b10000000 >>> 6) = 11100000 // -2
即使您从 & 操作中获得了正确的结果(通过在该点进行转换),>>>
将提升第一个操作数int
无论如何首先。
编辑:解决方案是改变掩盖事物的方式。不要使用 -64 进行掩码,而只需使用 128+64=192=0xc0 进行掩码:
byte foo = (byte)((bar & 0xc0) >>> 6);
这样一来,您实际上只留下您想要的两位,而不是在最高有效的 24 位中加载 1。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)