美文网首页
byte[]和int相关知识点

byte[]和int相关知识点

作者: 小豪丶ace | 来源:发表于2020-03-18 14:19 被阅读0次

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

    问题

    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

    相关文章

      网友评论

          本文标题:byte[]和int相关知识点

          本文链接:https://www.haomeiwen.com/subject/vhnqyhtx.html