如何在Excel中将四个字节的十六进制转换为浮点数

问题描述 投票:0回答:3

我已将 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

excel hex
3个回答
3
投票

多么伟大的使命啊!但对于任何感兴趣的人来说,我最终得到了一个自定义 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,我以前从未要求投票,但这花了我几周!如果你觉得它有用,请考虑给我打勾。)


0
投票

简短回答 = DEC2HEX('您的参考单元格或值')

当您从字符串中提取十六进制值时,您的公式会移动低字节和高字节的位置。十六进制就像所有其他基于位置的数字一样,最低值位于右侧。

此人解释如何在 Excel 中使用十六进制值

Debug of your formula

您可以在一个公式中使用多个阶段,例如:

=DEC2HEX(SUM(HEX2DEC("c240");HEX2DEC("d162")))

注意:如果您在 Office 中使用美国设置,请替换 ;与 ,


0
投票

我测试了你的功能,韦恩。完美完成!但当我在工作表中输入 3900 个值时,它显示出非常糟糕的性能。

因此,我想提出一个由 COM 库组成的替代解决方案。

图书馆代码:

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)。源代码可以使用任何文本编辑器进行编辑 - 易于修改、扩展和推进。

© www.soinside.com 2019 - 2024. All rights reserved.