byte[]和int相关知识点

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

问题

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

基础

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

原码,反码,补码

原码反码补码
+10000 00010000 00010000 0001
-11000 00011111 11101111 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]
补码00000000000000000000010011011110
真值004-34
代码解析
int a =1246
byte[] b = new byte[4]

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

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

补码00000000000000000000010011011110
右移24位00000000000000000000000000000000
& 0xff00000000000000000000000000000000
代码
b[0] = (byte) (a >> 24 & 0xff ) //值为 0;

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

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

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

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

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

补码00000000000000000000010011011110
右移0位00000000000000000000010011011110
& 0xff00000000000000000000000011011110

由于是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]对应的补码

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

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

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

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

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

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

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

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

b[0]补码00000000000000000000000000000000
b[1]补码00000000000000000000000000000000
b[2]补码00000000000000000000010000000000
b[3]补码00000000000000000000000011011110
逐个或运算00000000000000000000010011011110

补码对应的真值也为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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值