解析带小数的字节流
创始人
2025-05-28 21:07:48

设备协议的燃气价格是4字节,2字节整数,2字节小数,低位在前,它的16进制数据如何表示?
以数据2.06为例,说明下如何转16进制数据、如何解析16进制数据。

16进制表示

整数部分为2,小数部分为0.06
小数部分乘以10000,转成整数,0.06*10000 = 600
整数转为2字节的有符号整数,16进制表示为0x0002,小端模式为0x0200
小数转为2字节的有符号整数,16进制表示为0x0258,小端模式为0x5802
最终结果为0x58020200

为什么小数部分要乘以10000,而不是10、100、1000?
小数位占2字节,2字节表示的最大数是65535,假如小数位有5位,小数位最大位0.99999,乘以10000得到99999,很明显99999>65535;
假如小数位有4位,0.9999,乘以10000的到9999,很明显9999<65535,因此可得小数位最大为4位。

10进制表示

上面例子是低位在前,因此读取数据时要按照小端模式读取,代码如下:

{ByteBuf payload = ByteBufAllocator.DEFAULT.buffer();byte[] bytes = new byte[]{0x58, 0x02, 0x02, 0x00};payload.writeBytes(bytes);// 调用ByteBuf#readIntLE方法,按小端读取String data = DataUtil.hexToDecimalFor4Bytes(String.format("%08X", payload.readIntLE()), 2);System.out.println("16进制hex=2.06");System.out.println("解析16进制decimal=" + data);
}

工具方法:

 /*** 4字节数据转换* * @param hexData      4字节的16进制数据* @param integerBytes 整数所占字节数* @return*/
public static String hexToDecimalFor4Bytes(String hexData, int integerBytes) {// hexData = 00020258,因为获取数据是ByteBuf#readIntLE方法,按小端读取// 整数部分String left = hexData.substring(0, integerBytes * 2);// 小数部分String right = hexData.substring(integerBytes * 2);// 10进制整数部分Integer integer = Integer.valueOf(left, 16);// 10进制小数部分Integer decimal = Integer.valueOf(right, 16);// 小数字节数int decimalBytes = 4 - integerBytes;// 小数位数int decimalPowerOf2 = (int) Math.pow(2, decimalBytes);BigDecimal decimalBig = new BigDecimal(decimal);decimalBig.setScale(decimalPowerOf2);decimalBig = decimalBig.divide(new BigDecimal((int) Math.pow(100, decimalBytes)));BigDecimal result = decimalBig.add(new BigDecimal(integer));return result.toString();
}

相关内容

热门资讯

储户千万资金被商丘邮储银行理财... 伴随着银行理财经理王某姗及其丈夫孟某的先后自杀,两人身后留下的数千万元的资金谜团,正在成为公众关注的...
迟福林支招大湾区:“十五五”推... 本文来源:时代周报 作者:王晨婷“如果中国消费在全球的占比能够接近制造业的体量,中国将新增一个不低于...
全长131公里的高铁,浙西小城... 本文来源:时代周报 作者:曾思怡曾经被衢州称为“砸锅卖铁”也要上的杭衢高铁,已于12月26日通车。该...
农业机器人迎来“中国智造天团”... 2025年12月26日,农业机器人创新企业禾芯动力在北京成功举办以芯生·无界——禾芯动力全球品牌战略...
游客超1亿人次,消费超2000... 本文来源:时代周报 作者:阿力米热海南全岛封关运作启动,人们最直接的体验就是“免税打折”。三亚市商务...