我需要在Java中将一个字节转换为int,但我不希望使用符号扩展,所以我做了
byte b = -1
(int) (b & 0xF) // this returns 15, which is what I want
(int) (b | 0) // this returns -1, which is essentially 0xFFFF, sign extension happens, not what I want
我认为上面两个应该给出相同的结果,但结果却并非如此。 我必须在比特操作中遗漏一些东西。
答案 0 :(得分:2)
诀窍是打印这些值的二进制表示并对它们执行二进制操作
byte b = -1;
int a = (int) (b & 0xF); // this returns 15, which is what I want
int c = (int) (b | 0); // this returns -1, which is essentially 0xFFFF
System.out.println("b:" + Integer.toBinaryString(b));
System.out.println("a:" + Integer.toBinaryString(a));
System.out.println("c:" + Integer.toBinaryString(c));
System.out.println("0xF:" + Integer.toBinaryString(0xF));
打印
b:11111111111111111111111111111111
a:1111
c:11111111111111111111111111111111
0xF:1111
所以b & OxF
是
11111111111111111111111111111111
00000000000000000000000000001111 (AND)
--------------------------------
1111 (15)
和b | 0
是
11111111111111111111111111111111
00000000000000000000000000000000 (OR)
--------------------------------
11111111111111111111111111111111 (-1)
Hot Licks explains why the byte value -1
is represented in binary as it is.
答案 1 :(得分:1)
这里的问题是按位运算符处理整数或长整数,而不是字节。 b & 0xF
基本上被视为((int)b) & ((int)0xF)
。您可以从每个操作的JLS定义中跟踪所有操作。
&
)解释了当两个操作数都可以转换为整数基元类型时,“首先对操作数执行二进制数字提升(§5.6。 2)。“|
,float
或double
,否则这两个值都会扩展为long
。因此,在使用右操作数进行“与”或“或”运算之前,您的int
字节使用符号扩展名扩展为b
。
请注意,这意味着int
的结果应该是b & 0F
,而不是int
。事实上就是这种情况(意味着你明确地将它转发给byte
是多余的)。您可以通过将其自动装箱到int
然后检查该对象的类型来测试:
Object