前言
恰巧碰到了字节数组和整型的转换问题,特在此总结一下。将 int 按照小端法映射到 byte[] 中。即最低 8 位放在 byte[0] 中,依次类推。
一、int 转换为 byte[]
这个实现起来比较简单,先保存最低的 8 位到 byte 数组中,然后不断的右移 8 位,每次保存低 8 位数据即可,参考代码:(这里包含一个 int 到 byte 的转换,转换规则是截取 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));//截断 int 的低 8 位为一个字节 byte,并存储起来
return ans;
}
二、测试代码
为了验证转换结果,简单写了两个方法用来按位打印 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){//每四位为一组,用空格分开
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){//每四位为一组,用空格分开
System.out.print(" ");
count=0;
}
}
System.out.println();
}
三、测试
测试一下 int 到 byte[] 的正确性:用一个整数来测试一下,如下:
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]);
}
输出结果为:
1111 1111 1111 1111 0000 0000 0111 0001
0111 0001
0000 0000
1111 1111
1111 1111
算法执行无误。
四、byte[] 转换为 int
这个实现起来也比较简单, 每次将 byte 值保存到 int 的最低 8 位,然后 int 左移 8 位,继续保存新的 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;
}
验证一下(这一次采用整数 c 来说明问题,整数 d 恰好可以得到正确结果…):
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);
}
输出结果:
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:粗体显示和我们预料中的不太一样,其原因在于:语句 ans|=a[3-i];中,执行流程为:先将 byte a[3-i] 提升到 int ,然后再和 ans 取或操作,最后将结果赋给 ans。
在提升的过程中包含一个 byte 到 int 的转换,转换规则:如果 byte 值为负,即最高位为 1,那么在前面补上 24 个 1 凑够 32 位作为 int 的值,如果 byte 值为正,即最高位为 0,那么在前面补上 24个 0 得到新的 int 值。
为了每次在将 byte 转换为 int 时,前面都补上 0 ,这里可以将它先和 0xff 取 &。这里的 0xff 如果转换为 int 四字节的话为:0000 0000 0000 0000 0000 0000 1111 1111 。当然了,更加清晰的写法见下面代码。
修改之后的代码如下:
public static int bytesToInt(byte[] a){
int ans=0;
for(int i=0;i<4;i++){
ans<<=8;
ans|=(a[3-i]&0xff);
/* 这种写法会看起来更加清楚一些:
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;
}
输出结果:
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
能够看到可以得到正确结果。文章来源:https://www.toymoban.com/news/detail-411254.html
总结
需要注意的是:在 8 位 byte 提升到 32 位 int 时,由于数组在计算机中以补码形式存在,所以要区分正负的。正数前面补 0 ,负数前面补 1。而为了消除其差异性,仅保留我们所感兴趣的低 8 位,需要先将可能存在的 1 均变为 0,所以要先和 0xff 做 & 操作; 或者先提升到 int ,然后和0x000000ff 取 & 。文章来源地址https://www.toymoban.com/news/detail-411254.html
到了这里,关于Java 字节数组(byte[])和整型(int)的相互转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!