Java byte轉int為什么要用&0xff


我們查看很多源碼的時候都會看到在byte轉int的時候會&0xff,為什么會有這個操作呢。

byte[127]轉int

看下面代碼:


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

兩者的輸出都為127,看不出有什么問題。

byte[-127]轉int

我們將數值改為-127時


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


為什么&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);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM