问题点概括
在做3D智慧城市大数据数字孪生系统时,需要对温湿度传感设备上报的数据进行处理。其中涉及到16进制高位为1补码取负数问题,这里做个简单记录,予以往后扬嘴一笑的回忆。
具体处理流程
为了方便理解下面贴出通讯协议的温度解析部分介绍。
1、判断高位是否为1
拿到数据的第一步先来判断高位是否为1,Java中代码实现如下。
//这里的byte 就是接收到的16进制数据(0xFF9C、0x00FA等)
if ((byte & 0x80) == 0x80) {
//这里处理高位为1以后的逻辑
}
2、转为二进制
确定高位为1后将16进制字符串数据转成2进制,具体代码如下。
/**
* 16进制String转2进制bite
*
* @param hex
* @return
*/
public static byte[] hexStr2Byte(String hex) {
ByteBuffer bf = ByteBuffer.allocate(hex.length() / 2);
for (int i = 0; i < hex.length(); i++) {
String hexStr = hex.charAt(i) + "";
i++;
hexStr += hex.charAt(i);
byte b = (byte) Integer.parseInt(hexStr, 16);
bf.put(b);
}
return bf.array();
}
3、取反+1
对二进制数据取反并+1,具体实现代码如下。
// 2进制取反
String str2 = "";
byte temp;
for (int i = 0; i < bytes.length; i++) {
temp = bytes[i];
bytes[i] = (byte) (~temp);
str2 += Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1);
}
System.out.println("取反后二进制:" + str2);
// 取反后+1
String add_1 = Solution(str2, "1");
System.out.println("取反后二进制+1:" + add_1);
/**
* 两个二进制字符串求和
*
* @param a
* @param b
* @return
*/
public static String Solution(String a, String b) {
StringBuilder ans = new StringBuilder();
int ca = 0;
for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
int sum = ca;
sum += i >= 0 ? a.charAt(i) - '0' : 0;
sum += j >= 0 ? b.charAt(j) - '0' : 0;
ans.append(sum % 2);
ca = sum / 2;
}
ans.append(ca == 1 ? ca : "");
return ans.reverse().toString();
}
4、转回16进制或10进制
根据需求转回16进制或者其他进制数据即可,我这里直接转回10进制,实现代码如下。
// 将取反+1后的二进制字符串转10进制
int d = Integer.parseInt(add_1, 2);
System.out.println("二进制字符串转10进制:" + d);
整体Demo
为了方便理解,下面是我独立出来的整体实现代码,如有不对还望多多指教。
public static void main(String[] args) {
byte[] bytes = hexStr2Byte(hexStr);
// 2进制取反
String str2 = "";
byte temp;
for (int i = 0; i < bytes.length; i++) {
temp = bytes[i];
bytes[i] = (byte) (~temp);
str2 += Integer.toBinaryString((bytes[i] & 0xFF) + 0x100).substring(1);
}
System.out.println("取反后二进制:" + str2);
// 取反后+1
String add_1 = Solution(str2, "1");
System.out.println("取反后二进制+1:" + add_1);
// 将取反+1后的二进制字符串转10进制
int d = Integer.parseInt(add_1, 2);
System.out.println("二进制字符串转10进制:" + d);
}
/**
* 16进制String转2进制bite
*
* @param hex
* @return
*/
public static byte[] hexStr2Byte(String hex) {
ByteBuffer bf = ByteBuffer.allocate(hex.length() / 2);
for (int i = 0; i < hex.length(); i++) {
String hexStr = hex.charAt(i) + "";
i++;
hexStr += hex.charAt(i);
byte b = (byte) Integer.parseInt(hexStr, 16);
bf.put(b);
}
return bf.array();
}
/**
* 两个二进制字符串求和
*
* @param a
* @param b
* @return
*/
public static String Solution(String a, String b) {
StringBuilder ans = new StringBuilder();
int ca = 0;
for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
int sum = ca;
sum += i >= 0 ? a.charAt(i) - '0' : 0;
sum += j >= 0 ? b.charAt(j) - '0' : 0;
ans.append(sum % 2);
ca = sum / 2;
}
ans.append(ca == 1 ? ca : "");
return ans.reverse().toString();
}
THE END
感谢查阅
玉念聿辉:编辑