2015-09-17 74 views
2

我試圖簡化一些代碼解碼文件中的數據,我寫了一個測試用例來顯示這個問題。我可以簡化從二進制數據讀取短小

鑑於兩個字節爲0xFe0xFF我想, 現有的代碼確實

headerBuffer.get() & 0xff + (headerBuffer.get() & 0xff) * 256 

我想,如果我做了緩衝區的字節順序小端的是應該被理解成0xFFFE(65534),我能得到同樣的結果,閱讀作爲短。但我沒有得到相同的結果,爲什麼不呢?

headerBuffer.getShort();

public void testReadingOfShort() { 
    ByteBuffer headerBuffer = ByteBuffer.allocate(2); 
    headerBuffer.order(ByteOrder.LITTLE_ENDIAN); 
    headerBuffer.put((byte) 0xFE); 
    headerBuffer.put((byte)0xFF); 
    headerBuffer.position(0); 
    int format = headerBuffer.get() & 0xff + (headerBuffer.get() & 0xff) * 256; 
    headerBuffer.position(0); 
    int formatNew = headerBuffer.getShort(); 
    System.out.println("Format:"+format+"("+ Hex.asHex(format)+")"+":FormatNew:" 
      +formatNew+"("+Hex.asHex(formatNew)+")"); 
} 

輸出

Format:65534(0xfffe):FormatNew:-2(0xfffffffffffffffe)

+1

這是因爲一個'short'簽名!無論如何,我懷疑這裏的bug是在'Hex'類中的;顯示所有'.asHex()'方法的代碼 – fge

回答

3

你得到相同的值。

int formatNew = headerBuffer.getShort(); 

當你做到這一點,Java的執行符號擴展以確保在short的數值被換算成相同的數值:當你分配shortint在這條線的問題發生int。在你的情況下,這是-2。

作爲short的-2的表示是0xFFFE,而int表示是0xFFFFFFFE。換句話說,short的符號位被複制到int的附加高位中。

您可以通過不指定shortint來解決此問題。您還需要確保Hex.asHexshort有適當的過載,否則當formatNew作爲參數傳遞時會發生相同的轉換。

另外,如果你想治療short爲無符號的價值,並將其分配給一個int,你可以用0xFFFF掩蓋的結果,就像這樣:

int formatNew = headerBuffer.getShort() & 0xFFFF; 
+0

好吧我現在在Java中更好地理解它,因爲它的最大值是32,767,因此值爲0xffFe(65534)在短,但我不能使用ByteBuffers getInteger(),因爲我只想讀兩個字節而不是四個。所以我可以不分配它爲整數,問題是如果與其他值比如枚舉相比,所有文字都必須默認爲int,或者將&0xff分配給int,不確定這是最好的真的 –

+0

@PaulTaylor我編輯的時候添加了一種將'short'作爲無符號數的方式,當讀入'int'時。 – dasblinkenlight

0

我在這裏的假設是,在Hex類,你有一個.asHex()方法採取short作爲做類似的說法:

int value = (int) argument; 

真倒黴。如果您從一個整數類型「上傳」到另一個整數類型,則符號位(如果存在)。這意味着如果你試圖將一個簡短的0xfffe轉換爲一個int,那麼你將不會以0x0000fffe結束,而是...... 0xfffffffe。因此你的結果。

如果你想將它轉換爲無符號值,你不得不掩蓋它,就像這樣:

int value = (int) argument & 0xffff; 
0

你可以簡單地獲得所需的值

int formatNew = headerBuffer.getShort() & 0xFFFF; 

,或者如果你使用Java 8:

int formatNew = Short.toUnsignedInt(headerBuffer.getShort()); 

這將基本上是從int是沒有刪除所有的位t的一部分short。但是它不會免除您仔細檢查您期望無符號值的地方以及如何處理相應上下文中(自然)簽名的值的責任。