2013-11-29 65 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

相關問題