欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?int類型如何獲取高低位

 更新時間:2022年01月26日 14:44:54   作者:JAVA探索  
這篇文章主要介紹了Java?int類型如何獲取高低位,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

int類型如何獲取高低位

去年筆者和一個硬件廠商調(diào)試打印機(jī)的時候遇到這個一個問題,廠商需要打印報文中傳輸報文的長度標(biāo)志,按大端序,將長度的高位和低位放到兩個字節(jié)里,筆者由于基礎(chǔ)知識不牢固,在這個問題上浪費了較長時間,今年開始寫博客了,就記錄一下這個問題。筆者使用了int來記錄長度,其實應(yīng)該用兩個字節(jié)的short來記錄,這樣更簡單。

大小端序

要想拿int的高低位字節(jié),首先要理解大小端序。這里以int舉例,int有四個字節(jié)A,B,C,D。那么內(nèi)存里存儲int類型占用了四個字節(jié)的位置,這四個字節(jié)在內(nèi)存中肯定占用了連續(xù)遞增的四個地址,大小端序指得就是這四個字節(jié)在這四個地址中是順序排列的還是逆序排列的。如果是順序排列的,那么我們叫大端序,如果是逆序排列的,就叫小端序。

再拿網(wǎng)絡(luò)傳輸這個int值來舉例,甲向乙傳輸數(shù)據(jù),乙拿到甲傳的字節(jié)數(shù)組以后要知道怎么拼接這四個字節(jié),如果甲是按順序傳輸這四個字節(jié),而乙按逆序拼接四個字節(jié),那么雙方得到的int值肯定是不一樣的。那么怎么解決這個問題呢?方法就是雙方協(xié)定一個順序,比如按大端序傳輸,甲將四個字節(jié)按大端序傳輸給乙,乙再按大端序拼接字節(jié),這樣雙方得到的int值就是一樣的了。

總結(jié)一下就是,大端序,高位字節(jié)在前,低位字節(jié)在后。小端序,高位字節(jié)在后,低位字節(jié)在前。一般交互都是默認(rèn)大端序。

獲取int的高低位字節(jié)數(shù)組

這里給出了大小端序的int和字節(jié)數(shù)組互轉(zhuǎn)函數(shù)

 
    /**
     * 小端序 字節(jié)數(shù)組轉(zhuǎn)int
     *
     * @param bytes
     * @return
     */
    public static int littleEndian(byte[] bytes) {
        return (bytes[0]&0XFF)
                | ((bytes[1]&0XFF) << 8)
                | ((bytes[2]&0XFF) << 16)
                | ((bytes[3]&0XFF) << 24);
    }
 
    /**
     * 大端序 字節(jié)數(shù)組轉(zhuǎn)int
     *
     * @param bytes
     * @return
     */
    public static int bigEndian(byte[] bytes) {
        //System.out.println(String.format("%32s", Integer.toBinaryString(bytes[3]&0XFF)).replaceAll("\\s", "0"));
        //System.out.println(String.format("%32s", Integer.toBinaryString(((bytes[2]&0XFF) << 8)).replaceAll("\\s", "0")));
        //System.out.println(String.format("%32s", Integer.toBinaryString(((bytes[1]&0XFF) << 16)).replaceAll("\\s", "0")));
        //System.out.println(String.format("%32s", Integer.toBinaryString(((bytes[0]&0XFF) << 24)).replaceAll("\\s", "0")));
 
        return (bytes[3]&0XFF)
                | ((bytes[2]&0XFF) << 8)
                | ((bytes[1]&0XFF) << 16)
                | ((bytes[0]&0XFF) << 24);
    }
 
    /**
     * 大端序 int轉(zhuǎn)字節(jié)數(shù)組
     *
     * @param i
     * @return
     */
    public static byte[] bigEndian(int i) {
        int byte1 = i & 0XFF;
        int byte2 = (i & 0XFFFF) >>> 8;
        int byte3 = (i & 0XFFFFFF) >>> 16;
        int byte4 = (i & 0XFFFFFFFF) >>> 24;
        return new byte[]{(byte) byte4, (byte) byte3, (byte) byte2, (byte) byte1};
    }
 
    /**
     * 小端序 int轉(zhuǎn)字節(jié)數(shù)組
     *
     * @param i
     * @return
     */
    public static byte[] littleEndian(int i) {
        int byte1 = i & 0XFF;
        int byte2 = (i & 0XFF << 8) >> 8;
        int byte3 = (i & 0XFF << 16) >> 16;
        int byte4 = (i & 0XFF << 24) >> 24;
        return new byte[]{(byte) byte1, (byte) byte2, (byte) byte3, (byte) byte4};
    }
 
 
    public static void main(String[] args) {
        int a = new Random().nextInt();
        String s = String.format("%32s", Integer.toBinaryString(a)).replaceAll("\\s", "0");
        System.out.println("原數(shù)據(jù):             " + s.substring(0, 8) + " " + s.substring(8, 16) + " " + s.substring(16, 24) + " " + s.substring(24, 32) + " ");
 
        byte[] bytes = bigEndian(a);
        System.out.printf("大端序-int轉(zhuǎn)字節(jié)數(shù)組:");
        for (int i = 0; i < bytes.length; i++) {
            System.out.print(String.format("%8s", Integer.toBinaryString(bytes[i] & 0XFF)).replaceAll("\\s", "0") + " ");
        }
        System.out.println();
        System.out.println("大端序-字節(jié)數(shù)組轉(zhuǎn)int驗證:" + (bigEndian(bytes) == a));
 
        byte[] bytes2 = littleEndian(a);
        System.out.printf("小端序-int轉(zhuǎn)字節(jié)數(shù)組:");
        for (int i = 0; i < bytes2.length; i++) {
            System.out.print(String.format("%8s", Integer.toBinaryString(bytes2[i] & 0XFF)).replaceAll("\\s", "0") + " ");
        }
        System.out.println();
        System.out.println("小端序-字節(jié)數(shù)組轉(zhuǎn)int驗證:" + (littleEndian(bytes2) == a));
    }
}
 
原數(shù)據(jù):             10010100 11111001 01101110 00100011 
大端序-int轉(zhuǎn)字節(jié)數(shù)組:10010100 11111001 01101110 00100011 
大端序-字節(jié)數(shù)組轉(zhuǎn)int驗證:true
小端序-int轉(zhuǎn)字節(jié)數(shù)組:00100011 01101110 11111001 10010100 
小端序-字節(jié)數(shù)組轉(zhuǎn)int驗證:true

高低位和byte轉(zhuǎn)int

最近研究I/O流,發(fā)現(xiàn)read()方法返回的是int類型,原來是將一個byte讀入到一個int,有效的數(shù)據(jù)只占據(jù)int型變量的最低8位。在正常情況下這個int型的變量永遠(yuǎn)都不可能是負(fù)數(shù)。

什么是高低位?

一個Byte是8位(bit),其中的“8位”指的是8位2進(jìn)制數(shù)。byte范圍是-128--127,如果輸入超過這個數(shù)值,會編譯錯誤。

如8位二進(jìn)制數(shù):11001010;1100就是高4位,后面的1010就是低4位。

什么是低8位?

一個int類型的變量能存放4Byte,也就是能存放32位二進(jìn)制數(shù),而一個32位二進(jìn)制數(shù)中權(quán)值最大的24位就是高24位,那么剩下的就是低8位。

如何將byte轉(zhuǎn)換為int?

需要將前24位去除,也就是轉(zhuǎn)換為0。Java對byte總是做有符號處理;

所以可以通過將byte和0xff進(jìn)行二進(jìn)制“&“得到它的無符值。

例如:

byte的二進(jìn)制為:11001010;

0xff的二進(jìn)制為:11111111;

1111111111111111111111111 11001010 & 11111111 = 000000000000000000000000 11001010

上面的例子為什么會添加這么多“1”?

當(dāng)系統(tǒng)檢測到byte可能會轉(zhuǎn)化成int或者說byte與int類型進(jìn)行運(yùn)算的時候,就會將byte的內(nèi)存空間高位補(bǔ)1(也就是按符號位補(bǔ)位)擴(kuò)充到32位

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot中的CompletableFuture類詳解

    SpringBoot中的CompletableFuture類詳解

    這篇文章主要介紹了SpringBoot中的CompletableFuture類詳解,在?Java8中,引入了CompletableFuture類,它提供了一種簡單而強(qiáng)大的方式來執(zhí)行異步任務(wù),今天我們就來詳細(xì)解讀一下這個類,需要的朋友可以參考下
    2023-07-07
  • Java實現(xiàn)五子棋游戲

    Java實現(xiàn)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    這篇文章主要介紹了RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • SpringBoot啟動類@SpringBootApplication注解背后的秘密

    SpringBoot啟動類@SpringBootApplication注解背后的秘密

    這篇文章主要介紹了SpringBoot啟動類@SpringBootApplication注解背后的秘密,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Spring?Boot應(yīng)用程序中如何使用Keycloak詳解

    Spring?Boot應(yīng)用程序中如何使用Keycloak詳解

    這篇文章主要為大家介紹了Spring?Boot應(yīng)用程序中如何使用Keycloak詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • SpringBoot超詳細(xì)講解集成Flink的部署與打包方法

    SpringBoot超詳細(xì)講解集成Flink的部署與打包方法

    昨天折騰了下SpringBoot與Flink集成,實際上集成特簡單,主要是部署打包的問題折騰了不少時間。想打出的包直接可以java -jar運(yùn)行,同時也可以flink run運(yùn)行,或者在flink的dashboard上上傳點擊啟動。結(jié)果是不行,但是使用不同的插件打包還是可以的
    2022-05-05
  • java字符串的大寫字母右移實現(xiàn)方法

    java字符串的大寫字母右移實現(xiàn)方法

    下面小編就為大家?guī)硪黄猨ava字符串的大寫字母右移實現(xiàn)方法。小編覺得聽不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • Java創(chuàng)建線程的五種寫法總結(jié)

    Java創(chuàng)建線程的五種寫法總結(jié)

    本文主要為大家詳細(xì)介紹一下Java實現(xiàn)線程創(chuàng)建的五種寫法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)有一定的幫助,感興趣的可以跟隨小編學(xué)習(xí)一下
    2022-08-08
  • 自定義對象作為HashMap的Key問題

    自定義對象作為HashMap的Key問題

    這篇文章主要介紹了自定義對象作為HashMap的Key問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java壓縮集合的三種方法

    Java壓縮集合的三種方法

    這篇文章主要介紹了Java壓縮集合的三種方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01

最新評論