2015-03-31 61 views
0

这里的一个微小的java程序逻辑和算术移位的输出

public class otherclass { 
public static void main(String[]args){ 
     byte a=-5; 

     byte d= (byte) (a>>>1); 
     System.out.println(d); 
     byte e= (byte) (a>>>2); 
     System.out.println(e); 
     byte f= (byte) (a>>1); 
     System.out.println(f); 
     byte g= (byte) (a>>2); 
     System.out.println(g); 
} 
} 

输出:

-3 
-2 
-3 
-2 

第二两个输出(那些-3和-2的逻辑移位的)我明白了。

负5是11111011

算术移位向右移动并在左侧的额外添加的位是一样的MSB。所以一个移动使得11111101是负数3.负数2也是好的。

逻辑转变应该是零添加到左侧。 11111011应该变成01111101这就是125.它怎样输出负值3?

+0

注意,在类型'int'(4个字节)的值发生的偏移。 – 2015-03-31 22:35:52

+0

嗯,你是什么意思?它不适用于字节变量? – 2015-03-31 22:36:30

+0

它是一个整数类型,由由哪种类型确定的特定字节数表示。例如,'int'有32个字节。 'short'是16个字节,而'byte'是8。我不明白@SotiriosDelimanolis评论或者虽然 – 2015-03-31 22:38:56

回答

4

缺少的部分的信息是Java促进值int当比特移位它们,称为二进制数值提升。该byte值提升到int他们被转移之前,则发生偏移,然后将它们转换回byte

-5 as byte : 11111011 
-5 as int : 11111111 11111111 11111111 11111011 
Bit shifted : 01111111 11111111 11111111 11111101 

零移入,但剧组回byte抛弃这一切,但最后8位反正。

Cast to byte: 11111101 (-3) 

如果您希望>>>操作表现得好像没有二进制数值提升,那么你就必须从提升int屏蔽掉最后8位。

byte d= (byte) ((a & 0xFF)>>>1); 
System.out.println(d); 
byte e= (byte) ((a & 0xFF)>>>2); 
System.out.println(e); 

输出:

125 
62 

这里发生了什么:

-5 as byte : 11111011 
-5 as int : 11111111 11111111 11111111 11111011 
Bit masked : 00000000 00000000 00000000 11111011 
Bit shifted : 00000000 00000000 00000000 01111101 

零移入和以前一样,但剧组回byte抛弃这一切,但最后8位反正。

Cast to byte: 01111101 (125) 

请注意,这将与>>>>>发生,所以只能做到位,并与0xFF>>>操作。

+0

我明白了。那么回答这个问题。感谢那。但是现在我需要知道一种让java不做这种提升的转变方式。我想按照原样对字节进行转换。 – 2015-03-31 22:38:32

+0

我已经添加了解决方法。 – rgettman 2015-03-31 22:44:02

+0

非常好的解释! – 2015-03-31 22:44:34