Java有字符型转化为无字符型字节数组探索学习笔记

需要跟服务器进行socket通信,通信协议需要发送消息头,消息头是无符号型数据,java是没有无符号型的,所以需要转换,研究了下,下面是转换的测试。

数据存储范围知识:

要知道,有符号型对比无符号型来说,最高位是符号位,所以就存储数值来说,要想通过有符号型存储无符号符型,需要大一倍的存储空间。举个例子说,java的byte是一个字节8个比特,范围是-128~127,一个无符号型字节,范围应该是应该是0~256,所有java中要想存储到256,那应该至少需要2个字节,就可以通过short类型进行存储,short是两个字节,范围(-2的15次方到2的15次方-1)-32768~32767。所以同理,要想用有符号型存储无无符号型short,应该使用java的int进行存储,int就应该使用long。

注意: 无符号型,说明没有负数,可以表现负数,通过存储补码实现。

java中查看bit二进制:

可以通过以下方法查看每个字节的二进制码:

 public static String byteToBit(byte b) {
        return ""
                + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
                + (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
                + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
                + (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
    }

比如查看:byteToBit((byte)10),打印如下:

byte 10:00001010

将有符号型数据转化为无符号节数组数据:

如果有符号型数据大于0,直接转为字节数组就可以:

转化原理是,每个数据转为字节数据时,如果强制转型,会直接截取低位字节,这时可以通过右移使想要的字节移动到低位字节位置,然后通过强转获取到相应的字节。

 public static byte[] shortToBytes(int n) {
        byte[] intBytes = new byte[2];
        intBytes[0] = (byte) (n >> 8);
        intBytes[1] = (byte) (n >> 0);
        intBytes = Reverse(intBytes);//右移后,高低位反了
        return intBytes;
    }

    public static byte[] inToBytes(int n) {
        byte[] intBytes = new byte[4];
        intBytes[0] = (byte) (n >> 24);
        intBytes[1] = (byte) (n >> 16);
        intBytes[2] = (byte) (n >> 8);
        intBytes[3] = (byte) (n >> 0);
        intBytes = Reverse(intBytes);//右移后,高低位反了
        return intBytes;
    }

    private byte[] longToBytes(long n) {
        byte[] intBytes = new byte[8];
        intBytes[0] = (byte) (n >> 56);//可以写一个循环执行
        intBytes[1] = (byte) (n >> 48);
        intBytes[2] = (byte) (n >> 40);
        intBytes[3] = (byte) (n >> 32);
        intBytes[4] = (byte) (n >> 24);
        intBytes[5] = (byte) (n >> 16);
        intBytes[6] = (byte) (n >> 8);
        intBytes[7] = (byte) (n >> 0);
        intBytes = Reverse(intBytes);//右移后,高低位反了
        return intBytes;
    }

 public static int bytesToInt(byte[] b) {
        b  = Reverse(b);
        return   b[3] & 0xFF |// b[3] & 0xFF 1 3
                (b[2] & 0xFF) << 8 |//(b[2] & 0xFF) << 8 :1 2 <<8得到 2 0 ,1 3 |2 0 得到2 3
                (b[1] & 0xFF) << 16 |
                (b[0] & 0xFF) << 24;//最终得到0 1 2 3,因为开始反转了,所以是3 2 1 0

    }

    public static int bytesToShort(byte[] b) {
        b  = Reverse(b);
        return   b[1] & 0xFF |
                (b[0] & 0xFF) << 8;

    }
    public static byte[] Reverse(byte[] b) {
        byte[] temp = new byte[b.length];
        for (int i = 0; i < b.length; i++) {
            temp[i] = b[b.length - 1 - i];
        }
        return temp;
    }

如果有符号型数据小于0:

由于最高位是1,为符号位,对应于无符号类型数据是补码,所以直接转为补码就行了。补码计算方法为,获取原码,最高位不变,其余位取反,然后加1。
那是不是还要求补码呢,不需要了,因为计算机本来存储负数就是采用补码存储的,所以直接通过上面的方法计算出字节就可以了。

        short temp = -1;
        byte[] bs = BaseTypeDataByteUtil.inToBytes(temp);
        printByte(bs);

打印结果:11111111 11111111 11111111 11111111,这个就是-1的补码,-1的原码为10000000 0000000 0000000 00000001

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值