2009-07-03 149 views
1

嗯。考慮這個程序,其目標是找出將整數的底部16位作爲有符號整數的最佳方法。將Java int的底部16位作爲帶符號的16位值獲取

public class SignExtend16 { 
    public static int get16Bits(int x) 
    { 
     return (x & 0xffff) - ((x & 0x8000) << 1); 
    } 

    public static int get16Bits0(int x) 
    { 
     return (int)(short)(x); 
    }  

    public static void main(String[] args) 
    { 
     for (String s : args) 
     { 
      int x = Integer.parseInt(s); 
      System.out.printf("%08x => %08x, %08x\n", 
       x, get16Bits0(x), get16Bits(x)); 
     } 
    } 
} 

我打算用在get16Bits0的代碼,但我得到了「從短到int不必要鑄」與Eclipse的編譯器警告,這讓我懷疑,以爲編譯器可以優化我的「不必要投」 。當我使用Eclipse的編譯器在我的機器上運行它時,我得到了兩個函數的完全相同的結果,這些函數的行爲與我預期的相同(測試參數:1 1111 11111 33333 66666 99999)。這是否意味着我可以使用get16Bits0? (對於將來的代碼維護者有適當的警告)我一直認爲JRE和編譯器行爲對於算術都是獨立於機器的,但這種情況正在測試我的信仰。

回答

5

由於數字類型轉換是隱式友好的,我認爲你得到警告的唯一原因是編譯器總是在返回時將轉換爲int,這使得你的顯式轉換是多餘的。

+0

哦!謝謝!更好。 – 2009-07-03 17:10:18

0

是的,get16Bits0應該可以工作,只需在函數前添加一個suppressWarning元標籤即可。

5

那麼,首先警告是正確的,因爲你總是可以通過算術轉換移動「向上」。只有另一種方式需要轉換,因爲你可能會丟失數據(或浮點數的精度)。

當你從int減小到short時,你必須通過使用強制轉換來表明它是有意的。但是當你將短的值轉換回int時,沒有危險,它會自動發生。

因此,所有你需要的是

return (short) x; 
4

如果你想避免轉換,你可以做到這一點爲:

(x << 16) >> 16 

這種技術還可以與不同的比特數。說下15:

(X < < 17)>> 17

變化>>到>>>無符號版本。