Java byte轉int爲什麼要&0xff

總歸就是一句話,保證補碼的完整性

先看例子

byte[] b = new byte[1];
b[0] = -127;
// -127
System.out.print(b[0]);
// 129
System.out.print(b[0] & 0xff);

在此不再描述源碼、反碼、補碼的概念,但有個概念要提一下,‘數據擴展’,

數據擴展:

衆所周知計算機內二進制都是以補碼形式存儲的。byte類型的長度爲8bit,而int類型爲32bit。

在將低精度轉成高精度數據類型,有兩種擴展方案。

(1)補零擴展,能夠保證二進制存儲的一致性,但不能保證十進制值不變

(2)符號位擴展,能夠保證十進制值不變,但不能保證二進制存儲的一致性

對於正數來說這兩種是一樣的。當b[0] 爲127的時候,b[0] 補碼爲01111111

1.補零擴展以後爲00000000 00000000 00000000 01111111

2.符號位擴展以後也爲00000000 00000000 00000000 01111111

對於負數來說就不一樣了。當b[0] 爲-127的時候,b[0] 補碼爲10000001

1.補零擴展以後爲00000000 00000000 00000000 10000001

2.符號位擴展以後爲11111111 11111111 11111111 10000001

tips:Java對於有符號的擴展,使用的是符號位擴展來保證十進制的值不變。

即擴展以後爲11111111 11111111 11111111 10000001,其原碼就爲10000000 00000000 00000000 01111111,其十進制值爲-127

但是其二進制表示發生了變化補碼從10000001變爲了11111111 11111111 11111111 10000001

使用&0xff

所以很多時候爲了保證低八位的二進制不變,使用&0xff

`11111111 11111111 11111111 10000001 & 0xff =

11111111 11111111 11111111 10000001 & 11111111 =

00000000 00000000 00000000 10000001` 但是十進制變成了 129

實例 byte[]轉爲int

我們用實例看一下&0xff對轉換時的影響,如下所示我們期望得到的int00000000 00000000 00000001 10000001十進制爲385,如果不加&0xff則會得到-127。

tips:java 中對byte的所有運算操作均會是首先將byte轉化爲int, 再行運算

  byte[] bs = new byte[4];
         // 10000001
         bs[0] = (byte) -127;
         // 00000001
         bs[1] = (byte) 1;
         // 00000000
         bs[2] = (byte) 0;
         // 00000000
         bs[3] = (byte)0;
         
         // (bs[0]&0xff):00000000 00000000 00000000 10000001 或
         // (bs[1]&0xff):00000000 00000000 00000001 00000000
         // -----------------------------------
         //               00000000 00000000 00000001 10000001 或
         // (bs[2]&0xff):00000000 00000000 00000000 00000000
         // -----------------------------------
         //               00000000 00000000 00000001 10000001 或
         // (bs[3]&0xff):00000000 00000000 00000000 00000000
         // -----------------------------------
         //               00000000 00000000 00000001 10000001 正數 = 256+128+1=385
         
         int i = (bs[0]&0xff) | ((bs[1]& 0xff)<<8)| ((bs[2]& 0xff)<<16) | ((bs[3]& 0xff)<<24);
         
         // bs[0]:11111111 11111111 11111111 10000001 或
         // bs[1]:00000000 00000000 00000001 00000000
         // -----------------------------------
         //        11111111 11111111 11111111 10000001 或
         // bs[2]:00000000 00000000 00000000 00000000
         // -----------------------------------
         //        11111111 11111111 11111111 10000001 或
         // bs[3]:00000000 00000000 00000000 00000000
         // -----------------------------------
         // 這裏得到的是補碼(負數),需要轉成原碼
         // 11111111 11111111 11111111 10000001 - 1 
         // 11111111 11111111 11111111 10000000 取反
         // 10000000 00000000 00000000 01111111 = -127
         

         int k = (bs[0]) | ((bs[1])<<8)| ((bs[2])<<16) | ((bs[3])<<24);
         
         // 385
         System.out.print(i);
                 // -127
         System.out.print(k);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章