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