byte[]和int相关知识点

最近在项目中遇到了不太理解的地方,这里总结一下

问题

  1. 为什么int转byte可能是个负数
  2. &0xff的作用
  3. byte和int是怎么相互转化的

基础

在解释问题之前,了解一些计算机基础是很重要的

原码,反码,补码

原码 反码 补码
+1 0000 0001 0000 0001 0000 0001
-1 1000 0001 1111 1110 1111 1111
  1. 正数反码补码原码相同
  2. 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
  3. 负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1.

字节序(了解)

计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。

举例来说,数值0x2211使用两个字节储存:高位字节是0x22,低位字节是0x11。

理解字节序

两个知识点(重要)

  1. 计算机数的计算和存储是补码形式
  2. java只有有符号数

实例

有了上述概念,就可以举例说明了

int转byte可能是个负数

 int a=233;
 byte b=(byte)a;
 System.out.println(b);//结果为-23
 解析:  
 1.int是32位,233二进制补码形式(正数原码补码相同)  
 00000000 00000000 00000000 11101001[补码]  
 2.int转byte,byte是8位  
 (00000000 00000000 00000000) 11101001[补码]    
 3.去掉多余位数后剩下11101001[补码],求原码  
 11101001[补码]-> 10010111[原码] -> -23

&0xff的作用

  1. 只是为了取得低八位
  2. 保持补码一致性

byte和int是怎么相互转化的

int转byte

  1. 1246[补码] -> 00000000 00000000 00000100 11011110
  2. int是32位,byte是8位,所以将int转为byte需要4个字节
角标 [0] [1] [2] [3]
补码 00000000 00000000 00000100 11011110
真值 0 0 4 -34

代码解析

int a =1246
byte[] b = new byte[4]

由于byte只有8位,int有32位,所以需要通过右移运算,把每8位一组的值,移动到最后8位来计算,其他位忽略

第一步,求b[0]的值:

补码 00000000 00000000 00000100 11011110
右移24位 00000000 00000000 00000000 00000000
& 0xff 00000000 00000000 00000000 00000000
代码
b[0] = (byte) (a >> 24 & 0xff ) //值为 0;

第二步,求b[1]的值:

补码 00000000 00000000 00000100 11011110
右移16位 00000000 00000000 00000000 00000000
& 0xff 00000000 00000000 00000000 00000000
代码
b[1] = (byte) (a >> 16 & 0xff ) //值为 0;

第三步,求b[2]的值:

补码 00000000 00000000 00000100 11011110
右移8位 00000000 00000000 00000000 00000100
& 0xff 00000000 00000000 00000000 00000100
代码
b[2] = (byte) (a >> 8 & 0xff ) //值为 4;

第四步,求b[3]的值:

补码 00000000 00000000 00000100 11011110
右移0位 00000000 00000000 00000100 11011110
& 0xff 00000000 00000000 00000000 11011110

由于是int转byte,去除多余24位后11011110[补码]求真值为-34

代码
b[3] = (byte) (a  & 0xff ) //值为 -34;

完整代码

public static intToByteArr(int a){
  byte[] b = new byte[4]
  b[0] = (byte) (a >> 24 & 0xff )
  b[1] = (byte) (a >> 16 & 0xff )
  b[2] = (byte) (a >> 8 & 0xff )
  b[3] = (byte) (a  & 0xff )  
  return b;
}

byte[]转int

知道byte[] b = {0,0,4,-34}, 求int?只需把byte[]对应数的补码左移至原数对应的位置即可
第一步,b[0]对应的补码

补码 00000000 00000000 00000000 00000000
& 0xff 00000000 00000000 00000000 00000000
左移24位 00000000 00000000 00000000 00000000
代码
int a1 =  (b[0]  & 0xff )<<24 //值为 0;

第二步,b[1]对应的补码

补码 00000000 00000000 00000000 00000000
& 0xff 00000000 00000000 00000000 00000000
左移16位 00000000 00000000 00000000 00000000
代码
int a2 =  (b[1]  & 0xff )<<16 //值为 0;

第三步,b[2]对应的补码

补码 00000000 00000000 00000000 00000100
& 0xff 00000000 00000000 00000000 00000100
左移8位 00000000 00000000 00000100 00000000
代码
int a2 =  (b[2]  & 0xff )<<8 //值为 1024;

第四步,b[3]对应的补码

补码 11111111 11111111 11111111 11011110
& 0xff 00000000 00000000 00000000 11011110
代码
int a4 =  (b[3]  & 0xff ) //值为 222;

四个数相加起来结果1246
也可以这样理解

b[0]补码 00000000 00000000 00000000 00000000
b[1]补码 00000000 00000000 00000000 00000000
b[2]补码 00000000 00000000 00000100 00000000
b[3]补码 00000000 00000000 00000000 11011110
逐个或运算 00000000 00000000 00000100 11011110

补码对应的真值也为1246

完整代码

public static byteArrToInt(int a){
    int a1 =  (a[0]  & 0xff )<<24
    int a2 =  (a[1]  & 0xff )<<16 
    int a2 =  (a[2]  & 0xff )<<8
    int a3 =  (a[3]  & 0xff )
    return a1|a2|a3|a4;
}

参考

https://blog.csdn.net/wojiuai2093/article/details/50779879

猜你喜欢

转载自blog.csdn.net/acebleach/article/details/104947360