您的位置:首页 > 编程语言 > Java开发

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

2017-11-16 21:02 375 查看
需要跟服务器进行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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: