2009-02-19 48 views
10
byte x = -1; 
for(int i = 0; i < 8; i++) 
{ 
    x = (byte) (x >>> 1); 
    System.out.println("X: " + x); 
} 

據我所知,java存儲數據的二進制補碼,意思是-1 = 11111111(根據維基百科)。java位操作

另外,來自java文檔: 「位模式由左側操作數給出,右側操作數要移位的位置數,無符號右移運算符」>>>「移位零位置於最左邊的位置,而「>>」後面的最左邊位置取決於符號的擴展名。「

這意味着>>>每次都會將0移到最左邊的位。因此,我希望這個代碼是

迭代:X

的比特表示

0:11111111

1:01111111

2:00111111

3:00011111

。 .. so on

但是,我的輸出是alwa ys X:-1,這意味着(我猜)>>>將符號位放在最左邊的位置。所以我然後嘗試>>,並得到相同的結果。

發生了什麼事?我會希望我的輸出是:X:-1,x:127,x:63等

+0

這是在Java中謎題的問題之一。 – starblue 2009-02-19 07:49:44

回答

27

誰想到鑄造了一個int,當Java是發明,直到他們哭:-)

你可以做你想做的,應取出並毆打芹菜的溼粘字節應簽署並確保你從來沒有一個1移入最高位,這樣的事情:

byte x = -1; 
int x2 = ((int)x) & 0xff; 
for(int i = 0; i < 8; i++) 
{ 
    x2 = (x2 >>> 1); 
    System.out.println("X: " + x2); 
} 

你的具體問題是因爲>>>是鑄造了爲int做移位,那麼你鑄造它回如下所示:

byte x = -1; 
int x2 = ((int)x) & 0xff; 
int x3; 
int x4 = x2; 
for(int i = 0; i < 8; i++) 
{ 
    x2 = (x2 >>> 1); 
    System.out.println("X2: " + x2); 
    x3 = (x >>> 1); 
    x = (byte)x3; 
    x4 = (x4 >>> 1); 
    System.out.println("X: " + x3 + " " + x + " " + x4); 
} 

,輸出:

X2: 127 
X: 2147483647 -1 127 
X2: 63 
X: 2147483647 -1 63 
X2: 31 
X: 2147483647 -1 31 
X2: 15 
X: 2147483647 -1 15 
X2: 7 
X: 2147483647 -1 7 
X2: 3 
X: 2147483647 -1 3 
X2: 1 
X: 2147483647 -1 1 
X2: 0 
X: 2147483647 -1 0 

你可以清楚地看到,x和X3不工作(即使X3正確轉移,鑄造回字節X將其設置爲再次-1)。 x4完美運作。

+0

雖然這樣做工作(我欣賞幫助),它不向我解釋爲什麼我的代碼不起作用。 – jbu 2009-02-19 01:21:22

3

我不確定這一點。但是,我的猜測是,

x >>> 1 

從字節被提升爲int,因爲文字「1」是一個int。那麼你所觀察的是有道理的。

+0

我不這麼認爲。我改變了代碼,以確保它沒有得到晉升爲int: 字節x = -1; 對(INT I = 0; I <8;我++){ X =(字節)((字節)×>>(字節)1); System.out.println(「X:」+ x); } 輸出是一樣的,X:-1每次 – jbu 2009-02-19 01:18:03

+0

沒有幫助 - 當然,你轉換X和1個字節,但Java的應用向右移位運算符前自動轉換回整數。就我所知,沒有辦法直接應用位移到字節。 – 2009-02-19 01:24:32

0

我不知道爲什麼它不工作,但一個簡單的方法來清除最高位是&與(二進制)0111111:

x = (byte) (x >>> 1) & 0x7F; 
5

記住:

  • 位操作的操作數總是提升到至少一個int
  • 蒙上總是涉及符號擴展

所以,當你這樣做時(x >>> n),即使你將x定義爲一個字節,爲了移位的目的,它將首先轉換爲int。如果被轉換的字節是負數,那麼添加的所有「額外位」(因此,所得到的int的最左邊的24位)將被設置爲1。或換句話說,如果原始字節爲-1,則實際移動的東西是-1,如int,即32位數字,所有32位都設置爲1.將此右移1-8位仍然會導致最低8位全部設置爲1,因此當您將其轉換回一個字節時,您最終會得到一個所有8位都設置爲1的字節,換句話說,字節值爲-1。

0

的問題,因爲之前跟(很久以前),即X即可獲得upcasted做換班前爲int(符號擴展)。
做一個「位對位」的轉換應該有所幫助:

byte x = -1; 
for(int i = 0; i < 8; i++) 
{ 
    x = (byte) ((x & 0xFF) >>> 1); 
    System.out.println("X: " + x); 
}