当前位置: 首页 > article >正文

解析带小数的字节流

设备协议的燃气价格是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();
}

http://www.kler.cn/a/477.html

相关文章:

  • 浅谈下雪花算法的原理,及在项目中使用需要注意哪些事项
  • Java Stream流详解——串行版
  • 指针与数组:深入C语言的内存操作艺术
  • Docker部署GitLab服务器
  • 《QT 5.14.1 搭建 opencv 环境全攻略》
  • 在 RK3568 Linux 系统上使用 TUN 设备:详细教程
  • Graphics2D绘制图形详解
  • IIS发布.net6 api+微信小程序/H5真机调试接口的流程
  • 【SpringMVC】获取 -请求参数- 的多种方式
  • 《深入浅出WPF》——XAML语法及基础知识
  • 过来人告诉你:Java学到什么程度可以找工作?
  • C++【list容器模拟实现函数解析】
  • 【数据结构】万字超详解顺序表(比细狗还细)
  • 【MapGIS精品教程】013:如何制作三维电子沙盘?
  • 微信小程序开发学习笔记
  • spring cloud 企业工程项目管理系统源码+项目模块功能清单
  • Python人脸识别
  • 求最大公约数和最小公倍数---辗转相除法(欧几里得算法)
  • ConvMixer:Patches Are All You Need
  • MySql分页查询性能优化
  • 【c++类与对象 -- 补充 】
  • 编辑商品按钮显示商品对应数据
  • 时序预测 | MATLAB实现基于EMD-GRU时间序列预测(EMD分解结合GRU门控循环单元)
  • 【linux】:进程地址空间
  • 每周一算法:计数排序
  • 【Vue从入门到进阶】Node.js安装与配置