byte轉16進位制String時為什麼要乘上0xff

孤獨者的狂歡發表於2020-10-20

基本知識

1.byte是1byte(8位),int是4byte(32位)表示的。
2.Java中是使用了補碼的形式進行資料儲存的。
3.java中byte資料轉化為int資料時會自動補位,如果最高位(符號位)是0,則高24位全部補0,若是1,則高24位全部補1。

原因解析

如下程式碼:

public static String parseByte2HexStr(byte[] buf) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

正數

一個正數byte,轉為int時,前面補0。得到的依然是正數,而且值不變。
比如:1
byte 1=0000 0001 。轉為int 前面補0得到 0000 0000 0000 0000 0000 0000 0000 0001。所以做不做&0xff運算都一樣。

負數

負數byte,轉為int時,java為了保持值不變,預設前面補1。
比如:-1
byte -1二進位制以補碼儲存 11111 11111 。轉為int 前面補1得到 1111 1111 1111 1111 1111 1111 1111 1111。這個值在int確實是-1,但是如果Integer.toHexString()儲存為16進製得到0xffff ffff。當然我們可以用這個數儲存-1。

byte  i=(byte) (0xffffffff)
i=-1;

但是會有兩個問題:1、儲存的字元長度難以統一 2、字串長度太長。
byte的取值範圍在[-128,127]之間,16進製表示用兩個符號就夠了0x00—0xff。負數如果用這麼多字元,造成正負數符號長度不統一怎麼儲存呢?從16進位制還原成2進位制時怎麼按長度區分各個數字呢?

所以我們把byte與運算&0xff。以-1為例:1111 1111 1111 1111 1111 1111 1111 1111 & 0xff 得到 0000 0000 0000 0000 0000 0000 1111 1111 即0xff。這個數結果依然是-1。

byte  i=(byte) (0xff)
i=-1;

用這種方式處理後,byte不論正負,得到的都是二位的16進位制數。以兩位儲存,兩位還原,很方便。
也可以這樣還原。

以ff的16進位制數儲存:
byte i=(byte) (high * 16 + low);
i=-1;

總結

byte轉int時也是一樣的道理,-1與運算後得到0xff =255=1111 1111。把這個int轉為byte時就是-1。

相關文章