Java 字節(jié)數(shù)組(byte[])和整型(int)的相互轉(zhuǎn)換
前言
恰巧碰到了字節(jié)數(shù)組和整型的轉(zhuǎn)換問(wèn)題,特在此總結(jié)一下。將 int 按照小端法映射到 byte[] 中。即最低 8 位放在 byte[0] 中,依次類(lèi)推。
一、int 轉(zhuǎn)換為 byte[]
這個(gè)實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,先保存最低的 8 位到 byte 數(shù)組中,然后不斷的右移 8 位,每次保存低 8 位數(shù)據(jù)即可,參考代碼:(這里包含一個(gè) int 到 byte 的轉(zhuǎn)換,轉(zhuǎn)換規(guī)則是截取 int 的最低 8 位作為 byte 值)
public static byte[] intToBytes(int a){ byte[] ans=new byte[4]; for(int i=0;i<4;i++) ans[i]=(byte)(a>>(i*8));//截?cái)?int 的低 8 位為一個(gè)字節(jié) byte,并存儲(chǔ)起來(lái) return ans; }
二、測(cè)試代碼
為了驗(yàn)證轉(zhuǎn)換結(jié)果,簡(jiǎn)單寫(xiě)了兩個(gè)方法用來(lái)按位打印 int 和 byte,可參考如下:
public static void intPrint(int a){//將 int 按位從左到右打印 int count=0; for(int i=31;i>=0;i--){ System.out.print((a>>i)&1); count++; if(count==4){//每四位為一組,用空格分開(kāi) System.out.print(" "); count=0; } } System.out.println(); } public static void bytePrint(byte a){//將 byte 按位從左到右打印 int count=0; for(int i=7;i>=0;i--){ System.out.print((a>>i)&1); count++; if(count==4){//每四位為一組,用空格分開(kāi) System.out.print(" "); count=0; } } System.out.println(); }
三、測(cè)試
測(cè)試一下 int 到 byte[] 的正確性:用一個(gè)整數(shù)來(lái)測(cè)試一下,如下:
public static void main(String[] args) { int c=968523,d=-65423; byte[] ans=intToBytes(d); intPrint(d); for(int i=0;i<4;i++) bytePrint(ans[i]); }
輸出結(jié)果為:
1111 1111 1111 1111 0000 0000 0111 0001
0111 0001
0000 0000
1111 1111
1111 1111
算法執(zhí)行無(wú)誤。
四、byte[] 轉(zhuǎn)換為 int
這個(gè)實(shí)現(xiàn)起來(lái)也比較簡(jiǎn)單, 每次將 byte 值保存到 int 的最低 8 位,然后 int 左移 8 位,繼續(xù)保存新的 byte 值即可,參考代碼:
public static int bytesToInt(byte[] a){ int ans=0; for(int i=0;i<4;i++){ ans<<=8;//左移 8 位 ans|=a[3-i];//保存 byte 值到 ans 的最低 8 位上 intPrint(ans); } return ans; }
驗(yàn)證一下(這一次采用整數(shù) c 來(lái)說(shuō)明問(wèn)題,整數(shù) d 恰好可以得到正確結(jié)果…):
public static void main(String[] args) { int c=968523,d=-65423; byte[] ans=intToBytes(c); intPrint(c); for(int i=0;i<4;i++) bytePrint(ans[i]); int e=bytesToInt(ans); }
輸出結(jié)果:
0000 0000 0000 1110 1100 0111 0100 1011
0100 1011
1100 0111
0000 1110
0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1110
1111 1111 1111 1111 1111 1111 1100 0111 1111 1111 1111 1111 1100 0111 0100 1011
Error:粗體顯示和我們預(yù)料中的不太一樣,其原因在于:語(yǔ)句 ans|=a[3-i];中,執(zhí)行流程為:先將 byte a[3-i] 提升到 int ,然后再和 ans 取或操作,最后將結(jié)果賦給 ans。
在提升的過(guò)程中包含一個(gè) byte 到 int 的轉(zhuǎn)換,轉(zhuǎn)換規(guī)則:如果 byte 值為負(fù),即最高位為 1,那么在前面補(bǔ)上 24 個(gè) 1 湊夠 32 位作為 int 的值,如果 byte 值為正,即最高位為 0,那么在前面補(bǔ)上 24個(gè) 0 得到新的 int 值。
為了每次在將 byte 轉(zhuǎn)換為 int 時(shí),前面都補(bǔ)上 0 ,這里可以將它先和 0xff 取 &。這里的 0xff 如果轉(zhuǎn)換為 int 四字節(jié)的話為:0000 0000 0000 0000 0000 0000 1111 1111 。當(dāng)然了,更加清晰的寫(xiě)法見(jiàn)下面代碼。
修改之后的代碼如下:
public static int bytesToInt(byte[] a){ int ans=0; for(int i=0;i<4;i++){ ans<<=8; ans|=(a[3-i]&0xff); /* 這種寫(xiě)法會(huì)看起來(lái)更加清楚一些: int tmp=a[3-i]; tmp=tmp&0x000000ff; ans|=tmp;*/ intPrint(ans); } return ans; } public static void main(String[] args) { int c=968523,d=-65423; byte[] ans=intToBytes(c); intPrint(c); for(int i=0;i<4;i++) bytePrint(ans[i]); int e=bytesToInt(ans); return; }
輸出結(jié)果:
0000 0000 0000 1110 1100 0111 0100 1011
0100 1011
1100 0111
0000 1110
0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1110
0000 0000 0000 0000 0000 1110 1100 0111
0000 0000 0000 1110 1100 0111 0100 1011
能夠看到可以得到正確結(jié)果。
總結(jié)
需要注意的是:在 8 位 byte 提升到 32 位 int 時(shí),由于數(shù)組在計(jì)算機(jī)中以補(bǔ)碼形式存在,所以要區(qū)分正負(fù)的。正數(shù)前面補(bǔ) 0 ,負(fù)數(shù)前面補(bǔ) 1。而為了消除其差異性,僅保留我們所感興趣的低 8 位,需要先將可能存在的 1 均變?yōu)?0,所以要先和 0xff 做 & 操作; 或者先提升到 int ,然后和0x000000ff 取 & 。
到此這篇關(guān)于Java 字節(jié)數(shù)組(byte[])和整型(int)的相互轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Java 字節(jié)數(shù)組和整型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)Fibonacci(斐波那契)取余的示例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)Fibonacci取余的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03SpringBoot使用Sa-Token實(shí)現(xiàn)路徑攔截和特定接口放行
這篇文章主要介紹了SpringBoot使用Sa-Token實(shí)現(xiàn)路徑攔截和特定接口放行,文中通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-06-06簡(jiǎn)單講解奇偶排序算法及在Java數(shù)組中的實(shí)現(xiàn)
這篇文章主要介紹了奇偶排序算法及Java數(shù)組的實(shí)現(xiàn),奇偶排序的時(shí)間復(fù)雜度為O(N^2),需要的朋友可以參考下2016-04-04java如何讀取文件目錄返回樹(shù)形結(jié)構(gòu)
這篇文章主要介紹了java如何讀取文件目錄返回樹(shù)形結(jié)構(gòu)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Springboot 中使用 Aop代碼實(shí)戰(zhàn)教程
AOP的編程思想是把對(duì)類(lèi)對(duì)象的橫切問(wèn)題點(diǎn),從業(yè)務(wù)邏輯中分離出來(lái),從而達(dá)到解耦的目的,增加代碼的復(fù)用性,提高開(kāi)發(fā)效率,這篇文章主要介紹了Springboot中使用Aop代碼實(shí)戰(zhàn)教程,需要的朋友可以參考下2023-07-07java中實(shí)體類(lèi)實(shí)現(xiàn)時(shí)間日期自動(dòng)轉(zhuǎn)換方式
這篇文章主要介紹了java中實(shí)體類(lèi)實(shí)現(xiàn)時(shí)間日期自動(dòng)轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06Spring cloud alibaba之Gateway網(wǎng)關(guān)功能特征詳解
spring cloud gateway是spring cloud推出的第二代網(wǎng)關(guān),是由WebFlux+Netty+Reactor實(shí)現(xiàn)的響應(yīng)式的API網(wǎng)關(guān),它不能在傳統(tǒng)的servlet容器中工作,也不能構(gòu)建成war包,接下來(lái)通過(guò)本文給大家分享Spring cloud alibaba--Gateway網(wǎng)關(guān),需要的朋友可以參考下2021-08-08JPA中@CreatedDate和@LastModifiedDate的使用方式
這篇文章主要介紹了JPA中@CreatedDate和@LastModifiedDate的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11