为什么JAVA中的字节按位AND这样做?

时间:2013-04-27 12:26:32

标签: java char byte bit-manipulation bit

我正在搞乱按位运算符,我试图将负字节转换为无符号8位值,这就是人们的建议:

System.out.println(-20 & 0xFF); //bitwise AND on negative number and 255 

所以,这很好用,返回236,但为什么呢?就我而言:

00010100 //binary representation of -20
11111111 //binary representation of 0xFF or 255
--------
00010100 //it returns the same exact thing, so it's either -20 or 20

为什么会这样?我想我错过了一些非常简单的东西,但我似乎无法掌握它。

此外,如果我使用低于256的正数,则返回相同的数字。我似乎无法理解Java对这些数字的作用。

2 个答案:

答案 0 :(得分:4)

Java中的文字是int的形式。所以,当你说-20 & 0xFF时,就会发生这种情况:

  11111111 11111111 11111111 11101100 //-20 -ve nos are stored in 2's compliment form
& 00000000 00000000 00000000 11111111 // 0xFF 
  -------- -------- -------- --------
  00000000 00000000 00000000 11101100 // 236

由于negetaive值以2的赞美形式存储,因此得到值为236。

当您执行20 & 0xFF时,会发生这种情况:

  00000000 00000000 00000000 00010100 // 20 -ve nos are stored in 2's compliment form
& 00000000 00000000 00000000 11111111 // 0xFF 
  -------- -------- -------- --------
  00000000 00000000 00000000 00010100 // 20

答案 1 :(得分:1)

字节是以8位保存的有符号值,可以在-128到127范围内。

最左边的位用作符号位。

System.out.println(-20 & 0xFF);与字节无关,这是一个int操作。

-20的二进制表示,作为一个字节是:1110_1100

1110_1100& 1111_1111 = 1110_1100

如果你想要未签名,可以使用char,但你不会高兴。实际上,Java没有未签名。

否定以“2s补语”形式存储,例如:

1111_1111 == -1

但为什么?

在2s补码下得到一个负数,所有位都被翻转(1s补码)并且加1(使2s补码 - 两次运算)

所以

 0000_0000 - Zero
-0000_0001 - minus one
 ---------
 1111_1110 - Ones complement - (this would be xor 1111_1111)
+0000_0001 - plus one - we're converting to 2s complement, not doing math
 ---------
 1111_1111 - -1 in 2s complement