如何将电力仪表的两个整数转换为浮点数?现有方法存异常
问题分析
你当前的转换逻辑只在特定场景下有效:当两个16位整数的十六进制值恰好对应数字字符的ASCII码时(比如0x30对应'0'、0x31对应'1'),拼接后能得到正确的数字字符串。但当数值较大时,十六进制对应的ASCII字符不是数字(比如0x43对应'C'),转换自然失效。
电力仪表的浮点数据通常不会用ASCII字符串编码,而是采用32位IEEE 754单精度浮点数(最常见)或32位整数放大固定倍数(比如乘以10存储)的方式,以下是对应解决方案:
方案1:转换为IEEE 754单精度浮点数
大部分工业设备会用两个16位整数拼接成32位单精度浮点数,需要注意字节序(大端/小端,需参考仪表文档):
function WordsToReal(WordOne, WordTwo) { const w1 = $getTag(WordOne); const w2 = $getTag(WordTwo); // 创建4字节缓冲区存储32位数据 const buffer = new ArrayBuffer(4); const dataView = new DataView(buffer); // 示例:大端模式(WordOne为高16位,WordTwo为低16位) dataView.setUint16(0, w1, false); // false = 大端字节序 dataView.setUint16(2, w2, false); // 读取单精度浮点数,字节序需与写入一致 const floatValue = dataView.getFloat32(0, false); // 如果仪表数据是放大10倍存储(如你的例子19.1=191/10),则除以10 return floatValue / 10; }
如果测试后结果不对,尝试切换为小端模式(交换写入顺序并修改字节序参数):
// 小端模式(WordOne为低16位,WordTwo为高16位) dataView.setUint16(0, w1, true); // true = 小端字节序 dataView.setUint16(2, w2, true); const floatValue = dataView.getFloat32(0, true);
方案2:拼接为32位整数后转换
如果仪表是将实际值放大10倍后存储为32位整数,可直接拼接两个16位整数再除以10:
function WordsToReal(WordOne, WordTwo) { const w1 = $getTag(WordOne); const w2 = $getTag(WordTwo); // 示例:WordOne为高16位,WordTwo为低16位(大端) const int32Value = (w1 << 16) | (w2 & 0xFFFF); // 小端模式则交换顺序:(w2 << 16) | (w1 & 0xFFFF) return int32Value / 10; }
关键提示
- 必须参考电力仪表的通信协议文档,明确两个16位整数的字节序(大端/小端)和数据编码格式(IEEE754/整数放大),这是转换正确的核心。
- 若你的示例中w1=17358、w2=63971预期得到239.4,可优先测试方案1的字节序切换,或确认仪表是否有其他编码规则(如BCD码,但你的示例中存在非数字BCD值,可能性较低)。
内容的提问来源于stack exchange,提问作者Ionut
相关产品推荐
相关产品推荐

