byte爲什麼要&0xff?- java

byte爲什麼要&0xff?- java

半獸人 發表於: 2018-09-14   最後更新時間: 2018-09-14  

  •  
  •   26 訂閱,1677 遊覽

java 89

問答區 2 最新動態 1 實用工具 0

視頻 0

位與運算符(&)

運算規則:兩個數都轉爲二進制,然後從高位開始比較,如果兩個數都爲1則爲1,否則爲0。

比如:129&128

129轉換成二進制就是10000001,128轉換成二進制就是10000000。從高位開始比較得到,得到10000000,即128.

先看個例子:

public class Test {

    public static void main(String[] args) {
        byte[] a = new byte[10];
        a[0]= -127;
        System.out.println(a[0]);
        int c = a[0]&0xff;
        System.out.println(c);
    }
}

我先打印a[0],在打印a[0]&0xff後的值,本來結果應該都是-127.

但是結果真的是出人意料

-127
129

到底是爲什麼呢?&0xff反而不對了。

在學計算機原理的時候,計算機內的存儲都是利用二進制的補碼進行存儲的。

複習一下,原碼反碼補碼這三個概念

  • 對於正數(00000001)原碼來說,首位表示符號位,反碼,補碼都是本身
  • 對於負數(100000001)原碼來說,反碼是對原碼除了符號位之外作取反運算即(111111110),補碼是對反碼作+1運算即(111111111)

即:

  • 正數存儲的二進制原碼,
  • 負數存儲的是二進制的補碼。補碼是負數的絕對值反碼加1。

當將-127賦值給a[0]時候,a[0]作爲一個byte類型,其計算機存儲的補碼是10000001(8位)。

-127 二進制 描述
原碼 1111 1111  
反碼 1000 0000 高位不變,0變1,1變0
補碼 1000 0001 反碼 + 1

將 a[0] 作爲int類型向控制檯輸出的時候,jvm作了一個補位的處理,因爲int類型是32位所以補位後的補碼就是1111111111111111111111111 10000001(32位),這個32位二進制補碼錶示的也是-127

-127 二進制 描述
8位補碼 1000 0001 反碼 + 1
32位補碼 11111111 11111111 11111111 10000001 高位補1

但是我做byte->int的轉化的時候,只是爲了保持十進制的一致性嗎?

不一定吧?好比我們拿到的文件流轉成byte數組,難道我們關心的是byte數組的十進制的值是多少嗎?我們關心的是其背後二進制存儲的補碼

所以大家應該能猜到爲什麼byte類型的數字要&0xff再賦值給int類型,其本質原因就是想保持二進制補碼的一致性。

因爲當byte要轉化爲int的時候,高的24位必然會補1,這樣,其二進制補碼其實已經不一致了,&0xff可以將高的24位置爲0,低8位保持原樣。這樣就保證了二進制數據的一致性。

當然,保證了二進制數據性的同時,如果二進制被當作byte和int來解讀,其10進制的值必然是不同的,因爲符號位位置已經發生了變化。

結論

所以c的輸出的值就是129。有人問爲什麼上面的例子中a[0]不是8位而是32位,因爲當系統檢測到byte可能會轉化成int或者說byte與int類型進行運算的時候,就會將byte的內存空間高位補1(也就是按符號位補位)擴充到32位,再參與運算。

其實是從數字類型擴展到較寬的類型時,補擴展還是補符號位擴展。

這是因爲Java中只有有符號數,當byte擴展到short, int時,即正數都一樣,因爲爲符號位是0,所以無論如何都是補零擴展;

但負數補零擴展和按符號位擴展結果完全不同。補符號數,原數值不變。

補零時,相當於把有符號數看成無符號數,比如-127 = 0x81,看成無符號數就是129, 256 + (- 127)

對於有符號數,從小擴展大時,需要用&0xff這樣方式來確保是按補零擴展。

而從大向小處理,符號位自動無效,所以不用處理。

也就是說在byte向int擴展的時候,自動轉型是按符號位擴展的,這樣子能保證十進制的數值不會變化,而&0xff保持低位不變,高位轉化爲0,這樣子能保證二進制存儲的一致性,但是十進制數值已經發生變化了。也就是說按符號位擴展能保證十進制數值不變,而&0xff能保證二進制存儲不會變。而正數可以說是既按符號位擴展,又是補0擴展,所以在二進制存儲和十進制數值上都能保證一致。

發佈了177 篇原創文章 · 獲贊 147 · 訪問量 166萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章