java位操作

byte x = -1; for(int i = 0; i >> 1); System.out.println("X: " + x); } 

据我了解,java以二进制补码存储数据,意思是-1 = 11111111(根据维基百科)。

此外,从java文档:“位模式由左侧操作数给出,以及由右侧操作数移位的位置数。无符号右移位运算符”>>>“将零移位到最左侧位置,而“>>”后面的最左边位置取决于符号扩展。“

这意味着>>>每次都会将0移到最左边的位。 所以我期待这段代码

迭代:x的位表示

0:11111111

1:01111111

2:00111111

3:00011111

……等等

但是,我的输出总是X:-1,这意味着(我猜)>>>将符号位放在最左边的位置。 所以我然后尝试>>,同样的结果。

这是怎么回事? 我希望我的输出为:X:-1,x:127,x:63等。

谁想到在Java发明时应该签名字节的人应该拿出来用芹菜的湿棍子打败,直到他们哭:-)

您可以通过转换为int来执行您想要的操作,并确保您永远不会将1转换为顶部位,如下所示:

 byte x = -1; int x2 = ((int)x) & 0xff; for(int i = 0; i < 8; i++) { x2 = (x2 >>> 1); System.out.println("X: " + x2); } 

你的特殊问题是因为>>>正在转换为int来进行移位,然后你将它转换回一个字节,如下所示:

 byte x = -1; int x2 = ((int)x) & 0xff; int x3; int x4 = x2; for(int i = 0; i < 8; i++) { x2 = (x2 >>> 1); System.out.println("X2: " + x2); x3 = (x >>> 1); x = (byte)x3; x4 = (x4 >>> 1); System.out.println("X: " + x3 + " " + x + " " + x4); } 

哪个输出:

 X2: 127 X: 2147483647 -1 127 X2: 63 X: 2147483647 -1 63 X2: 31 X: 2147483647 -1 31 X2: 15 X: 2147483647 -1 15 X2: 7 X: 2147483647 -1 7 X2: 3 X: 2147483647 -1 3 X2: 1 X: 2147483647 -1 1 X2: 0 X: 2147483647 -1 0 

您可以清楚地看到x和x3不起作用(即使x3正确移位,将其转换回x中的字节再次将其设置为-1)。 x4完美运作。

请记住:

  • 按位运算的操作数总是被提升为至少一个int
  • 演员阵容总是涉及签名延期

所以当你这样做(x >>> n)时,即使你将x定义为一个字节,出于移位的目的,它也会首先转换为int。 如果被转换的字节是负数,那么所有添加到“int”的“额外位”(因此,最终的int的最左边24位)将被设置为1.或者换一种方式,如果是原始的byte是-1,你实际上移位的是-1作为int ,即32位数,所有32位都设置为1.将右移1到8位仍然会导致底部8位全部设置为1,因此当你转回一个字节时,你得到一个字节,其中所有8位设置为1,或者换句话说,字节值为-1。

我不确定这个。 但是,我猜是这样的

 x >>> 1 

从字节升级到int,因为文字“1”是一个int。 然后你所观察到的是有道理的。

我不知道为什么它不起作用,但清除最高位的简单方法是与(二进制)0111111:

 x = (byte) (x >>> 1) & 0x7F; 

问题是,如前所述(很久以前),x在进行转换之前会升级为int(符号扩展)。
执行“位到位”转换应该有助于:

 byte x = -1; for(int i = 0; i < 8; i++) { x = (byte) ((x & 0xFF) >>> 1); System.out.println("X: " + x); }