1. 程式人生 > >java byte轉int 互相轉換原理詳解

java byte轉int 互相轉換原理詳解

轉自:https://blog.csdn.net/wojiuai2093/article/details/50779879

int i = 0;
  i += ((b[0] & 0xff) << 24);
  i += ((b[1] & 0xff) << 16);
  i += ((b[2] & 0xff) << 8);
  i += ((b[3] & 0xff));

想必大家對這樣的程式碼並不陌生,明白就可以不看了,想了解的繼續往下看,不好的地方還請多多包涵!
個人經常看到這樣的寫法但是不明白為何,所以忽然想了解下於是研究了下.

有一定的計算機2進位制計算基礎的就可以看明白,如果不明白2進位制,先去看看計算機2進位制計算及轉換之類的東西

 

===========開始...

原碼,反碼,補碼概念
+1原 = 0000 0001
-1原  = 1000 0001
反碼
正數的反碼是其本身
負數的反碼是在其原碼的基礎上, 符號位不變,其餘各個位取反.
補碼
正數的補碼就是其本身
負數的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1. (即在反碼的基礎上+1)

一部分int轉byte
java採用[補碼]儲存整數 int型為4位元組 32位,byte為1位元組8位
所以byte[]陣列中儲存一個int型別肯定是4個1位元組的byte組成,即byte[4]才可以存放一個int值
就算int 是0在計算中也是佔用個32位表示:00000000 00000000 00000000 00000000 存入byte中即4個下標中均為0
int直接存入byte陣列中及原理:

int a =1246;
二進位制表示
|------高16位----------|  |---------低16位-------|
00000000 00000000 00000100 11011110
|   A         | |   B        | |   C         | |   D         |
[0]              [1]             [2]              [3]   放入byte[]陣列原理,將這個2進位制以8位為1個位元組存入byte陣列中從陣列下標0開始存入
最後byte[]陣列儲存為這樣
[0]=00000000   補碼後00000000轉10進位制真實數值0
[1]=00000000   補碼後00000000轉10進位制真實數值0
[2]=00000100   補碼後00000100轉10進位制真實數值4
[3]=11011110   補碼後10100010轉10進位制真實數值-34,
                         最後8位11011110最高位是符合位,1負0正,補碼規則: 符號位不變, 其餘各位取反, 
                         最後+1得到:10100010 0100010=34+負號"1"所以=-34
轉換過程中進行&運算就是高位捨去,通俗就是不需要的資料清0處理,下面琢行說明:

由於byte只有8位,int32位,所以我們需要位移,把前面的每8位一組移動到最後8位上面來進行計算,其他數值都不參與計算
int a =1246;
byte[] b = new byte[4];
第一步:
b[0] = (byte) (a >> 24 & 0xff);
將00000000 00000000 00000100 11011110 A區域移動到D區域往右邊推動24位,主要獲取A取的值
00000000 00000000 00000100 11011110
                                                   00000000 00000000 00000100 11011110形成這樣的
空白的資料被抹掉就是0表示,移動後超出了D區域資料屬於溢位情況也舍掉最後形成如下
00000000 00000000 00000000 00000000
最後做&計算,這裡移動了24位,右邊的資料都被溢位了,做不做這個計算都沒影響,還是表示下
00000000 00000000 00000000 00000000
00000000 00000000 00000000 11111111  &計算0xFF的2進位制
-------------------------------------------------------
 00000000 00000000 00000000 00000000 結果還是0

第二步:
b[1] = (byte) ((a >> 16) & 0xff);
將00000000 00000000 00000100 11011110 B區域移動到D區域往右邊推動16位,主要獲取B取的值
00000000 00000000 00000100 11011110
                                  00000000 00000000 00000100 11011110形成這樣的
空白的資料被抹掉就是0表示,移動後超出了D區域資料屬於溢位情況也舍掉最後形成如下
00000000 00000000 00000000 00000000
00000000 00000000 00000000 11111111  &計算0xFF的2進位制
---------------------------------------------------------
00000000 00000000 00000000 00000000 結果還是0

第三步:
b[2] = (byte) ((a >> 8) & 0xff);
將00000000 00000000 00000100 11011110 C區域移動到D區域往右邊推動8位,主要獲取C取的值
00000000 00000000 00000100 11011110
                 00000000 00000000 00000100 11011110形成這樣的
空白的資料被抹掉就是0表示,移動後超出了D區域資料屬於溢位情況也舍掉最後形成如下
00000000 00000000 00000000 00000100
00000000 00000000 00000000 11111111  &計算0xFF的2進位制
-------------------------------------------------------
00000000 00000000 00000000 00000100補碼後的2進位制,上面的每一步最後都要參與補碼,只是因為0就沒寫了
 轉10進位制最終結果是4

第四步:
b[3] = (byte) (a & 0xff);
將00000000 00000000 00000100 11011110 計算D區的值,由於D取直接就是在末尾8位上,所以不需要移動,
直接&計算,這裡充分體現出來&0xFF計算就是清除其餘不需要的資料,由於8位前還有0100 這麼個數,
但是我們只需要後8位,所以&FF計算清除掉
00000000 00000000 00000100 11011110
00000000 00000000 00000000 11111111  &計算0xFF的2進位制
-------------------------------------------------------
00000000 00000000 00000000 11011110結果
這個結果轉10進位制:222,可見是有問題的,int->byte我們只需要拿出最後8位出來進行處理11011110,
上面提過最高位(左邊0的位置)是符號位:0表示正數,1表示負數
計算過程中只看後面7位1011110轉10進位制:94加上前面的符號得到-94,但這個數也不對
因為java採用補碼儲存整數
所以我們需要對1011110這個負數進行補碼:負數的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1. (即在反碼的基礎上+1)
1011110
1100001再+1 1100001+1=1100010
最後1100010轉10進位制(只看後面7位100010):34前面加符號-34才是最終結果


二部分byte轉int
對於一個單一的byte轉int就是其本身,因為byte範圍是-128--127如果輸入超過這個數直接編譯不通過
byte i=12;
int c=(int)i;
c=12;

像前面一部分,int轉byte後得到的是一個4位元組的byte[]陣列,因為int長度就是4位元組,不管值有多大或是0 byte[]也是4個長度,裡面的值都是0;
繼續上面的最終byte[]陣列中的結果是
byte[] b ={0,0,4,-34};從下標0-4存的是int型別的高位到低位的順序
|------高16位-----------| |---------低16位--------|
00000000 00000000 00000100 11011110
|   0         | |   0         | |   4         | |  -34        |
int 到byte是向右移動,那轉換回來就是反其道而行之

第一步:
00000000 00000000 00000100 11011110原2進位制
                                                   00000000 00000000 00000100 11011110原來下標0的數被移右動24位
所以獲取下標[0]<<24左移24位
下標[0]=0轉2進位制
00000000 00000000 00000000 00000000  左移24位後的2進位制,因為0怎麼移動都是0
00000000 00000000 00000000 11111111  再進行&FF運算,為何要&FF後面比較直觀,這裡是0所以不講解了
00000000 00000000 00000000 00000000  補碼
-----------------------------------------
結果0

第二步:
00000000 00000000 00000100 11011110原2進位制
                                  00000000 00000000 00000100 11011110原來下標1的數被移右動16位
所以獲取下標[1]<<16左移16位,當然後面的2組數以不存在,移動後整個32位的2進位制就是如下
下標[1]=0轉2進位制00000000
00000000 00000000 00000000 00000000  左移16位後的2進位制,因為0怎麼移動都是0
00000000 00000000 00000000 11111111  再進行&FF運算,為何要&FF後面比較直觀,這裡是0所以不講解了
00000000 00000000 00000000 00000000  補碼
-----------------------------------------
結果0

第三部分:
00000000 00000000 00000100 11011110原2進位制
                 00000000 00000000 00000100 11011110原來下標2的數被移右動8位
所以獲取下標[2]<<8左移8位,當然後面的1組數以不存在,移動後整個32位的2進位制就是如下
下標[2]=4轉2進位制00000100
 00000000 00000000 00000100 00000000  左移8位後的2進位制
&00000000 00000000 00000000 11111111  再進行&FF運算,為何要&FF後面比較直觀,這裡是0所以不講解了
-----------------------------------------
 00000000 00000000 00000100 00000000
 00000000 00000000 00000100 00000000補碼,正數補碼是其本身
 結果100 00000000轉10進位制=1024

第四部分:
下標[3]=-34轉2進位制11111111 11111111 11111111 11011110
11111111 11111111 11111111 11011110原來下標3的數就是末尾8位沒有發生過移動,所以不需要位移
00000000 00000000 00000000 11111111這裡比較直觀&FF計算去掉不需要的資料,可以稱作清0操作
-----------------------------------------
00000000 00000000 00000000 11011110結果
00000000 00000000 00000000 11011110補碼後
這時11011110並不是負數,因為現在是byte轉int上面進行&FF運算後最高位是0,所以是正數,正數補碼就是本身
-----------------------------------------
所以轉10進位制後=222
將最終的4個結果相加0+0+1024+222=1246