java二进制字节转换

#前言
好久都没有写博客,最近一直我可能要疯狂的写博客了,上几周吸收了很多的知识,接触的都是0和1,睡觉都是0和1,急躁的内心,我都开始有点掉头发了


#转型
最开始的时候对于转型问题真的是没有太多的理解,只是知道向上转型和向下转型,高的如果向下装丢失数据,所以下可以向上转型,但是从来没有深刻的体会到对于计算机内容的转型,下面说一下具体实例来吧


##实例
首先说一下int类型是4个字节,short是2个字节,1个字节代表的是8位,下面我说的是关于int类型转换为short类型
short类型大小为最小值:
Short.MIN_VALUE=-32768 (-2的15此方)
最大值:Short.MAX_VALUE=32767 (2的15次方-1)
int类型大小
最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)
最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)


最开始的时候我没有注意到转型问题,然后让int类型直接转换为short类型,但是突然间发现有问题,可以看出32769完全超出了我们的长度,所以这个时候再java里面是由正负号的(C中是没有的),所以这个时候最终的short会是负数的,但是你会发现的就是这样也没有关系,因为在java里面他直接都帮助我们处理,用负数进行代替了,所以比较方便。
这里写图片描述


下面我需要做的就是不能使用short类型,直接使用int类型,之前的short是2个byte,前在是int类型,所以会是4个字节,32位,下面的内容就是转换问题,和具体的步骤
1.把int类型转换为32位的字节
2抽取后16位字节
3把16字节转换为2字节,2个字节正好是short类型
4然后put进行

在这里要说明的就是字节和字有的时候会搞混,字节是用数组表示的,例如byte[] 里面存储的是0,1,对于字他表示的byte。一个字节8个字,也就是8位,位就是字


       byte[] bytes= Utilities.intToByte32(32769);
       //声明一个二进制的16字节的数组
        byte[] byteshort=new byte[16];
        //要知道16字节里面有32位,所以我们从16的index开始取数据存储到byteshort数组里面
        System.arraycopy(bytes,16,byteshort,0,byteshort.length);
        //把16字节的数组转换为2个字节,也是short类型。
        this.MessageID=Utilities.byte16ToShort(byteshort);
        //最后一步是放到我们的缓冲区中
        byteBuf.putShort(this.MessageID);

    /**
     *将int转换为32位byte.
     * 实际上每个8位byte只存储了一个0或1的数字
     * 比较浪费. 
     * @param num
     * @return
     */
    public static byte[] intToByte32(int num) {
        byte[] arr = new byte[32];
        for (int i = 31; i >= 0; i--) {
            // &1 也可以改为num&0x01,表示取最地位数字.
            arr[i] = (byte) (num & 1);
            // 右移一位.
            num >>= 1;
        }
        return arr;
    }

    /**
     * byte转换为short类型
     *
     * @param arr
     * @return
     */
    public static short byte16ToShort(byte[] arr) {
        if (arr == null || arr.length != 16) {
            throw new IllegalArgumentException("byte数组必须不为空,并且长度为16!");
        }
        short sum = 0;
        for (int i = 0; i < 16; ++i) {
            sum |= (arr[i] << (15 - i));
        }
        return sum;
    }

##java中位运算符
可能我写了上面的代码之后你还是不太明白,下面我们得把java中的为运算符搞通,在java中我们会遇到二进制位运算,并且他们在运算的时候会自动的转换为二进制进行运算
位运算符有:
1.&与运算
2.I或匀速
3.~ 取反运算
4.>>向右移动,指的是二进制的数的index
5.<< 向左移动
6.>>> 无符号向右移动,不足补0

另外说一下,在java中我们使用的是补码进行运算,也就是源码进行反码,然后再进行补码,最后就是我们java的运行方式,所以你会在java中看见有负数,但是在C中你是看不见负数的,这就是他们之间的区别

原码:如果当前的是的十进制是-1,那么用二进制表示就是1 000 0001,最高位表示负数
反码:对于反码来说整数就是原码,但是对于负数来说,就是处符号位以外取反,所以就变成:1 111 1110
补码:就是在原有的反码基础上加1,所以结果就是1111 1111


#总结
通过这次的深入了解让我对于java的内存中运算有了不一样的理解,发现真的是又恨又爱,刚开始真的不会,天天发愁,感觉头发都在掉,不过还好,回过头看,才知道自己在那里栽坑了,在byte[]里面他可以放二进制,也可以放十进制,也可以放16进制,所以这个时候需要你转,有的时候数组越界也要检查清楚,因为是从0开始,所以你最后要减一。下一篇见解buffer。你是否对于数据包封装和解析充满好奇呢?期待下下篇把。。。

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王雪芬-ghqr-264962

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值