總歸就是一句話,保證補碼的完整性
先看例子
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);