我正在搞乱按位运算符,我试图将负字节转换为无符号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对这些数字的作用。
答案 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