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二进制:
可以通过以下方法查看每个字节的二进制码:
比如查看:byteToBit((byte)10),打印如下:
将有符号型数据转化为无符号节数组数据:
如果有符号型数据大于0,直接转为字节数组就可以:
转化原理是,每个数据转为字节数据时,如果强制转型,会直接截取低位字节,这时可以通过右移使想要的字节移动到低位字节位置,然后通过强转获取到相应的字节。
如果有符号型数据小于0:
由于最高位是1,为符号位,对应于无符号类型数据是补码,所以直接转为补码就行了。补码计算方法为,获取原码,最高位不变,其余位取反,然后加1。
那是不是还要求补码呢,不需要了,因为计算机本来存储负数就是采用补码存储的,所以直接通过上面的方法计算出字节就可以了。
打印结果:11111111 11111111 11111111 11111111,这个就是-1的补码,-1的原码为10000000 0000000 0000000 00000001
数据存储范围知识:
要知道,有符号型对比无符号型来说,最高位是符号位,所以就存储数值来说,要想通过有符号型存储无符号符型,需要大一倍的存储空间。举个例子说,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
相关文章推荐
- JNI学习笔记5——本地方法处理java数组/引用问题/缓存jfieldID/jmethodID
- java数组学习笔记二:
- Java容器类学习笔记2--数组排序
- Java IO学习笔记:字节流
- JAVA学习笔记(4)数组(简)
- Java学习笔记之数组复习
- Java学习笔记-数组与ArrayList
- 【Java学习笔记】数组的相关事项
- Java学习笔记2 - 数组的基本操作
- JNI学习笔记:(1)开篇(2)本地代码访问Java代码 (3)本地方法取得Java属性/调用java方法 (4)本地代码创建Java对象(包括javaString) (5) 本地方法处理java数组
- java学习笔记之数组
- java学习笔记---数组
- Java学习笔记003——继承、抽象类、类相等测试、泛型数组列表、可变参数方法
- Java IO学习笔记:字节流
- java学习笔记(十九)对象数组
- Java基础学习笔记(二)数组,包装类
- Java学习笔记---5.Java数组和方法
- java数组学习笔记
- Java 数组 容器 学习笔记
- Java IO学习笔记(四):字节-字符转换流