• byte -> int


    传送门

    传送门2

    以下copy:

     int i = 0;
      i += ((b[0] & 0xff) << 24);
      i += ((b[1] & 0xff) << 16);
      i += ((b[2] & 0xff) << 8);
      i += ((b[3] & 0xff));

    想必大家对这样的代码并不陌生,明白就可以不看了,想了解的继续往下看,不好的地方还请多多包涵!
    个人经常看到这样的写法但是不明白为何,所以忽然想了解下于是研究了下.

    有一定的计算机2进制计算基础的就可以看明白,如果不明白2进制,先去看看计算机2进制计算及转换之类的东西

    ===========开始...

    原码,反码,补码概念
    +1原 = 0000 0001
    -1原  = 1000 0001
    反码
    正数的反码是其本身
    负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
    补码
    正数的补码就是其本身
    负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

    一部分int转byte
    Java采用[补码]存储整数 int型为4字节 32位,byte为1字节8位
    所以byte[]数组中存储一个int类型肯定是4个1字节的byte组成,即byte[4]才可以存放一个int值
    就算int 是0在计算中也是占用个32位表示:00000000 00000000 00000000 00000000 存入byte中即4个下标中均为0
    int直接存入byte数组中及原理:

    int a =1246;
    二进制表示
    |------高16位----------|  |---------低16位-------|
    00000000 00000000 00000100 11011110
    |   A         | |   B        | |   C         | |   D         |
    [0]              [1]             [2]              [3]   放入byte[]数组原理,将这个2进制以8位为1个字节存入byte数组中从数组下标0开始存入
    最后byte[]数组存储为这样
    [0]=00000000   补码后00000000转10进制真实数值0
    [1]=00000000   补码后00000000转10进制真实数值0
    [2]=00000100   补码后00000100转10进制真实数值4
    [3]=11011110   补码后10100010转10进制真实数值-34,
                             最后8位11011110最高位是符合位,1负0正,补码规则: 符号位不变, 其余各位取反,
                             最后+1得到:10100010 0100010=34+负号"1"所以=-34
    转换过程中进行&运算就是高位舍去,通俗就是不需要的数据清0处理,下面琢行说明:

    由于byte只有8位,int32位,所以我们需要位移,把前面的每8位一组移动到最后8位上面来进行计算,其他数值都不参与计算
    int a =1246;
    byte[] b = new byte[4];
    第一步:
    b[0] = (byte) (a >> 24 & 0xff);
    将00000000 00000000 00000100 11011110 A区域移动到D区域往右边推动24位,主要获取A取的值
    00000000 00000000 00000100 11011110
                                                       00000000 00000000 00000100 11011110形成这样的
    空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
    00000000 00000000 00000000 00000000
    最后做&计算,这里移动了24位,右边的数据都被溢出了,做不做这个计算都没影响,还是表示下
    00000000 00000000 00000000 00000000
    00000000 00000000 00000000 11111111  &计算0xFF的2进制
    -------------------------------------------------------
     00000000 00000000 00000000 00000000 结果还是0

    第二步:
    b[1] = (byte) ((a >> 16) & 0xff);
    将00000000 00000000 00000100 11011110 B区域移动到D区域往右边推动16位,主要获取B取的值
    00000000 00000000 00000100 11011110
                                      00000000 00000000 00000100 11011110形成这样的
    空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
    00000000 00000000 00000000 00000000
    00000000 00000000 00000000 11111111  &计算0xFF的2进制
    ---------------------------------------------------------
    00000000 00000000 00000000 00000000 结果还是0

    第三步:
    b[2] = (byte) ((a >> 8) & 0xff);
    将00000000 00000000 00000100 11011110 C区域移动到D区域往右边推动8位,主要获取C取的值
    00000000 00000000 00000100 11011110
                     00000000 00000000 00000100 11011110形成这样的
    空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
    00000000 00000000 00000000 00000100
    00000000 00000000 00000000 11111111  &计算0xFF的2进制
    -------------------------------------------------------
    00000000 00000000 00000000 00000100补码后的2进制,上面的每一步最后都要参与补码,只是因为0就没写了
     转10进制最终结果是4

    第四步:
    b[3] = (byte) (a & 0xff);
    将00000000 00000000 00000100 11011110 计算D区的值,由于D取直接就是在末尾8位上,所以不需要移动,
    直接&计算,这里充分体现出来&0xFF计算就是清除其余不需要的数据,由于8位前还有0100 这么个数,
    但是我们只需要后8位,所以&FF计算清除掉
    00000000 00000000 00000100 11011110
    00000000 00000000 00000000 11111111  &计算0xFF的2进制
    -------------------------------------------------------
    00000000 00000000 00000000 11011110结果
    这个结果转10进制:222,可见是有问题的,int->byte我们只需要拿出最后8位出来进行处理11011110,
    上面提过最高位(左边0的位置)是符号位:0表示正数,1表示负数
    计算过程中只看后面7位1011110转10进制:94加上前面的符号得到-94,但这个数也不对
    因为java采用补码存储整数
    所以我们需要对1011110这个负数进行补码:负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
    1011110
    1100001再+1 1100001+1=1100010
    最后1100010转10进制(只看后面7位100010):34前面加符号-34才是最终结果


    二部分byte转int
    对于一个单一的byte转int就是其本身,因为byte范围是-128--127如果输入超过这个数直接编译不通过
    byte i=12;
    int c=(int)i;
    c=12;

    像前面一部分,int转byte后得到的是一个4字节的byte[]数组,因为int长度就是4字节,不管值有多大或是0 byte[]也是4个长度,里面的值都是0;
    继续上面的最终byte[]数组中的结果是
    byte[] b ={0,0,4,-34};从下标0-4存的是int类型的高位到低位的顺序
    |------高16位-----------| |---------低16位--------|
    00000000 00000000 00000100 11011110
    |   0         | |   0         | |   4         | |  -34        |
    int 到byte是向右移动,那转换回来就是反其道而行之

    第一步:
    00000000 00000000 00000100 11011110原2进制
                                                       00000000 00000000 00000100 11011110原来下标0的数被移右动24位
    所以获取下标[0]<<24左移24位
    下标[0]=0转2进制
    00000000 00000000 00000000 00000000  左移24位后的2进制,因为0怎么移动都是0
    00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
    00000000 00000000 00000000 00000000  补码
    -----------------------------------------
    结果0

    第二步:
    00000000 00000000 00000100 11011110原2进制
                                      00000000 00000000 00000100 11011110原来下标1的数被移右动16位
    所以获取下标[1]<<16左移16位,当然后面的2组数以不存在,移动后整个32位的2进制就是如下
    下标[1]=0转2进制00000000
    00000000 00000000 00000000 00000000  左移16位后的2进制,因为0怎么移动都是0
    00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
    00000000 00000000 00000000 00000000  补码
    -----------------------------------------
    结果0

    第三部分:
    00000000 00000000 00000100 11011110原2进制
                     00000000 00000000 00000100 11011110原来下标2的数被移右动8位
    所以获取下标[2]<<8左移8位,当然后面的1组数以不存在,移动后整个32位的2进制就是如下
    下标[2]=4转2进制00000100
     00000000 00000000 00000100 00000000  左移8位后的2进制
    &00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
    -----------------------------------------
     00000000 00000000 00000100 00000000
     00000000 00000000 00000100 00000000补码,正数补码是其本身
     结果100 00000000转10进制=1024

    第四部分:
    下标[3]=-34转2进制11111111 11111111 11111111 11011110
    11111111 11111111 11111111 11011110原来下标3的数就是末尾8位没有发生过移动,所以不需要位移
    00000000 00000000 00000000 11111111这里比较直观&FF计算去掉不需要的数据,可以称作清0操作
    -----------------------------------------
    00000000 00000000 00000000 11011110结果
    00000000 00000000 00000000 11011110补码后
    这时11011110并不是负数,因为现在是byte转int上面进行&FF运算后最高位是0,所以是正数,正数补码就是本身
    -----------------------------------------
    所以转10进制后=222
    将最终的4个结果相加0+0+1024+222=1246

    --------------------- 本文来自 曦语 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_31232515/article/details/75009161?utm_source=copy

  • 相关阅读:
    C++程序设计第二周作业
    navicat 连接windows服务器中的mysql数据库
    Python 多进程(二度回顾)
    MySQl 合并结构相同的多张表
    Python 验证码识别-- tesserocr
    Navicat Premium 修改MySQL密码(忘记密码的情况下)
    Navicat Premium 出现2059错误解决办法
    MySQL 1053错误 服务无法正常启动的解决方法
    mysql触发器trigger 实例详解
    navicat for mysql 连接报错1251详细解决步骤
  • 原文地址:https://www.cnblogs.com/jztsdwn/p/9752654.html
Copyright © 2020-2023  润新知