2012-12-07 36 views
1

對於從字節到整數的轉換,我有點困惑。請看下面的代碼:將字節轉換爲整數時的問題(Java特定?)

byte[] data = new byte[] { 0, (byte) 0xF0 }; 

int masked = data[0] << 8 & 0xFF | data[1] & 0xFF; //240 
int notMasked = data[0] << 8 | data[1]; //-16 

因爲在Java字節簽署,不是240小數,而是2的補,-16。但是,它應該仍然是二進制:0x11110000那麼,爲什麼我需要做data[1] & 0xFF

Java是否將所有內容都轉換爲Integer,然後將其傳遞給|運算符?爲什麼&0xFF然後呢?

+1

我前段時間做了一些代碼的C到Java端口,它使用了很多按位操作,並提出了一個[helper class](https://github.com/pillingworthz/level9j/blob/master/src/java/uk /co/threeonefour/l9/vm/Conv.java)讓事情變得更簡單。沒有關於這些質量或效率的保證,但他們爲我做了這份工作。 – pauli

回答

4

Java字節被簽名(不幸) - 所以當您將值提升到int以執行按位|時,它最終會被標記爲0xFFFFFFF0。然後用data[0]混淆了|。用& 0xff屏蔽將其轉換爲240的整數值(僅爲0x000000F0)。

但是,你已經有一個問題。此代碼:

int masked = data[0] << 8 & 0xFF | data[1] & 0xFF; 

應該是:

int masked = ((data[0] & 0xff) << 8) | (data[1] & 0xFF); 

...否則你後掩蔽的轉變,這是行不通的。我已經添加了括號,因爲我從來沒有肯定的&<<|的predence的...

+0

啊哈!所以'|'和'&'都被提升爲整數,所以'&0xFF'在整數值*上發生。這完全解釋它,非常感謝! – Miquel

+1

@Miquel:'&0xFF'確實升級爲'int',所以'|'不必,如果你看到我的意思:) –

+0

後續行動:這當然是Java特定的,但是其他語言照着做? – Miquel

1

這是衆所周知的類似 「拼圖」

byte x = -1; 
x = x >>>= 1; 
System.out.println(x); 

產生

-1 

不換班?這是因爲在編譯arithemtic /移位/比較表達式之前的javac促進字節(以及短期和炭)爲int或長(如果有任何長在表達),因此它的工作原理如下

x -> int = 0xFFFFFFFF; 0xFFFFFFF >>> 1 = 0x7FFFFFF; (byte)0x7FFFFFF -> 0xFF 
+0

好:)但只是沒有人會感到困惑:你在這裏使用帶符號的移位運算符('>>>')而不是正常的運算符('>>') – Miquel

+0

好吧,我認爲>>>被稱爲無符號的,否則沒有難題,是嗎? –