我已将 Wireshark 捕获的十六进制数据流作为不带空格的文本值复制到 Excel 中。
04000000ffffffff2b010000c900000000000000000000000000000000000000
我知道如何使用以下公式将其中的一部分转换为 Excel 中的整数:
=HEX2DEC(MID(B173,19,2) & MID(B173,17,2))
在本例中返回 299。
但是我该如何做类似的事情来检索浮点数呢?我发现一些文章讨论编写 C# 程序,但我只是尝试在 Excel 中设置一个小调试环境。其他文章似乎只讨论在另一个方向上进行转换,但我无法弄清楚相反的过程。
编辑:我所追求的一个例子是:
=SOMEFUNCTION("d162c240")
--> 6.062(我认为)
或者可能
=SOMEFUNCTION("c240" & "d162")
--> 6.062
多么伟大的使命啊!但对于任何感兴趣的人来说,我最终得到了一个自定义 LAMBDA 函数HexToFloat(),该函数是在不需要 VBA 的情况下构建的。使用的 LAMBDA 函数和其他几个函数是 Excel 365 中的新函数 - 如果您在重现下面的函数时遇到错误,则您可能使用的是旧版本。
维基百科页面单精度浮点格式是我的主要参考,特别是将二进制32转换为十进制部分。
阅读本文以充分理解(祝你好运!!),但对于 TLDR 来说,值得注意的是,有一个隐含位实际上并未存储在内存中,当与分数部分结合时,这被称为“有效数” .
对于我的解决方案,我必须在 Excel 的名称管理器中构建几个支持 LAMBDA 函数。就我而言,数据存储为 Little-Endian,因此如果这不适用于您的情况,您可以跳过该步骤。
姓名 | 评论 |
---|---|
LittleEndianHex | 通过以 2 字节块反转十六进制数据将其解释为 Little Endian |
=LAMBDA(HexData,MID(HexData,7,2) & MID(HexData,5,2) & MID(HexData,3,2) & MID(HexData,1,2))
姓名 | 评论 |
---|---|
十六进制转BIN | 处理比本机 Excel HEX2BIN 函数更大的数字 |
=LAMBDA(number,[places],LET(Unpadded,REDUCE("",HEX2BIN(MID(number,SEQUENCE(LEN(number)),1),4),LAMBDA(result,byte,result & byte)),REPT("0",IF(ISOMITTED(places),0,places-LEN(Unpadded))) & Unpadded))
姓名 | 评论 |
---|---|
BIN转DEC | 处理比本机 Excel BIN2DEC 函数更大的数字 |
=LAMBDA(E,SUMPRODUCT(MID("0"&E,ROW(INDIRECT("1:"&LEN("0"&E))),1)*2^(LEN("0"&E)-ROW(INDIRECT("1:"&LEN("0"&E))))))
姓名 | 评论 |
---|---|
十六进制转浮点 | 将小端 IEEE 754 二进制 32(4 字节)数字的十六进制表示形式转换为单精度浮点格式 |
=LAMBDA(HexData,LET(LEHex,LittleEndianHex(HexData),Binary,HEXtoBIN(LEHex,32),bSign,LEFT(Binary,1),bExponent,MID(Binary,2,8),bImplicit,IF(bExponent=REPT("0",8),"0","1"),bSignificand,bImplicit & RIGHT(Binary,23),dSign,BIN2DEC(bSign),dExponent,BINtoDEC(bExponent),dSignificand,BINtoDEC(bSignificand),(-1)^dSign*(dSignificand*2^-23)*2^(dExponent-127)))
完成所有这些后,您可以将 HexToFloat 公式直接输入到单元格中,例如
=HexToFloat(A1)
或=HexToFloat("d162c240")
。此特定示例返回结果 6.07456254959106。
(PS,我以前从未要求投票,但这花了我几周!如果你觉得它有用,请考虑给我打勾。)
简短回答 = DEC2HEX('您的参考单元格或值')
当您从字符串中提取十六进制值时,您的公式会移动低字节和高字节的位置。十六进制就像所有其他基于位置的数字一样,最低值位于右侧。
您可以在一个公式中使用多个阶段,例如:
=DEC2HEX(SUM(HEX2DEC("c240");HEX2DEC("d162")))
注意:如果您在 Office 中使用美国设置,请替换 ;与 ,
我测试了你的功能,韦恩。完美完成!但当我在工作表中输入 3900 个值时,它显示出非常糟糕的性能。
图书馆代码:
using System;
using System.Reflection;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Globalization;
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IModbUtils {
[Description("Conversion error")]
bool Error{get; set;}
[Description("Convert 4 bytes hexadecimal string to float")]
float Hex2Float(string hexstr);
}
[Description("Utilities for MODBUS data processing")]
[ClassInterface(ClassInterfaceType.None)]
public class clModbUtils : IModbUtils{
public bool Error{get; set;}
public float Hex2Float(string hexstr){
float result = 0; Error = false;
try {
if (string.IsNullOrWhiteSpace(hexstr)) Error = true;
else {
var bts = BitConverter.GetBytes(Int32.Parse(hexstr, NumberStyles.HexNumber));
byte[] bytes = new byte[4];
bytes[0] = bts[2]; bytes[1] = bts[3];
bytes[2] = bts[0]; bytes[3] = bts[1];
result = BitConverter.ToSingle(bytes, 0);
}
}
catch { Error = true; }
return result;
}
}
Hex2Float 接受由 Online Hex Converter 标识的“Mid-Little Endian (CDAB)”十六进制字符串。它与 MODBUS 传输中的顺序匹配(低字在前)。
要编译并注册库,请使用:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe -target:library -platform:x64 ModbUtils.cs
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe -tlb -codebase ModbUtils.dll
它需要.NET Framework 4.8(较低版本也应该合适)。该平台应与 Excel 平台匹配。对于 32b,请使用上面的“\Framework\”和“platform:x86”。
当然,可以创建成熟的 Excel 插件,但我使用的方法需要较少的工具(没有 Visual Studio)。源代码可以使用任何文本编辑器进行编辑 - 易于修改、扩展和推进。