2013-11-29 29 views
1

我需要转换一个字节在Java诠释,但我不想符号扩展,所以我也为什么位或操作会导致符号扩展,但有点不会?

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

做一个或用'0'给对方号码:您可以通过它自动装箱到Object,然后检查对象的类型进行测试。你在问什么? –

+0

不,我的意思是我认为0 | ((字节)-1)应该是15,但实际上它是-1。 – NSF

+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.

+0

你的链接是自引用的... –

+0

@SteveP。它链接到HotLicks的评论。 –

+0

+1为酷链接 – NSF

1

这里的问题是整数或多头,而不是字节是位运算符的工作。 b & 0xF基本上被视为((int)b) & ((int)0xF)。您可以从每个操作的JLS定义中追踪所有内容。

  • 首先JLS 15.22.1(定义&|)解释的是,当两个操作数都是可转换为整数的原始类型,“二进制数值提升首先对操作数(§5.6.2)中进行。”
  • JLS 5.6.2反过来说,除非任一操作数是float,doublelong,这两个值都被扩大为int
  • 最后,在JLS 5.1.2中定义了加宽,并且指出:“扩展有符号整数值到整数类型T的转换只是简单地扩展整数值的二进制补码表示以填充更宽的格式。”字节被签名(JLS 4.2)。

所以,你b字节加宽到int使用符号扩展为AND'd之前或与右操作数或运算。

请注意,这意味着b & 0F的结果应该是int而不是byte。这实际上就是这种情况(这意味着你明确地将它转换成int是多余的)。

byte b = -1; 
Object o = (b & 0xF); 
System.out.println(o.getClass()); 
// prints "class java.lang.Integer", not "class java.lang.Byte" 
+0

适用于语言标准 – NSF

相关问题