C# 将IEEE754格式响应转换为C中的双精度值#

C# 将IEEE754格式响应转换为C中的双精度值#,c#,serial-port,modbus,rs485,C#,Serial Port,Modbus,Rs485,如何将IEEE754格式的浮点返回值转换为可读值 设备的响应返回为02 03 04 43 5D 38 10 5F 69,其中: 02-从机地址 03-功能代码 04-字节计数 43 5D 38 10-从设备返回的值 5F 69-CRC 下面是我使用的代码: void ModbusHandler() { try { while (run) { byte[] resp = new byte[9]; whi

如何将IEEE754格式的浮点返回值转换为可读值

设备的响应返回为
02 03 04 43 5D 38 10 5F 69
,其中:

02-从机地址 03-功能代码 04-字节计数 43 5D 38 10-从设备返回的值 5F 69-CRC

下面是我使用的代码:

void ModbusHandler()
{
    try
    {
        while (run)
        {
            byte[] resp = new byte[9];
            while (!modread.TheReadingFunction(startaddr, datalength, devid, fn, ref resp)) ;
            if (resp != null)
            {
                if (!dataevents.IsDisposed)
                    UpdateTextBox( PrintBytes(resp));
                string myFloat = floatConversion(resp).ToString();
                if (!dataevents.IsDisposed)
                    UpdateTextBox($"Conversion: {myFloat}");

                double val0 = ToFloat(resp);
                if (!dataevents.IsDisposed)
                    UpdateTextBox($"Value 0: {val0}");

                double val1 = Math.Round(Convert.ToDouble(resp[3] << 8 | resp[4] & 0xFF), 3, MidpointRounding.AwayFromZero);
                if (!dataevents.IsDisposed)
                    UpdateTextBox($"Value 1: {val1}");

                double val2 = Math.Round(Convert.ToDouble(resp[5] << 8 | resp[6] & 0xFF), 3, MidpointRounding.AwayFromZero);
                if (!dataevents.IsDisposed)
                    UpdateTextBox($"Value 2: {val2}");

                double res1 = (resp[3] << 8 | resp[4] & 0xFF);
                double res2 = (resp[5] << 8 | resp[6] & 0xFF);
                if (!dataevents.IsDisposed)
                    UpdateTextBox($"Byte 1: {res1}|Byte 2: {res2}");
            }
            else
            {
                if (!dataevents.IsDisposed)
                    UpdateTextBox("Reponse is null");
            }
        }
    }
    catch (Exception err)
    {
        if (!dataevents.IsDisposed)
            UpdateTextBox($"Error in modbus read: {err.Message.ToString()}");
    }
}
float floatConversion(byte[] data)
{
    float result = BitConverter.ToSingle(BitConverter.IsLittleEndian ? data.Reverse().ToArray() : data, 0);
    return result;
}
float ToFloat(byte[] input)
{
    byte[] newArray = new[] { input[2], input[3], input[0], input[1] };
    return BitConverter.ToSingle(newArray, 0);
}

设备上的当前值为~207.686V这是一个功率计

如果结果为221.219V,则:

Array.Reverse(resp, 3, 4); 
float volts = BitConverter.ToSingle(resp, 3)

您的IEEE754数字是以大端为单位的(而您的计算机是以小端为单位的),因此您可以反转字节并进行转换。

如果结果是真的221.219V,则:

Array.Reverse(resp, 3, 4); 
float volts = BitConverter.ToSingle(resp, 3)

您的IEEE754数字是以大端为单位的(而您的计算机是以小端为单位的),因此您可以反转字节并进行转换。

您确定响应告诉您IEEE754中的电压吗?因为207.686将是
9eaf4f43
,所以您可以自己查看它:
Single sing=207.686f;var iee=BitConverter.GetBytes(sing);Console.WriteLine(位转换器.ToString(iee))如果实际结果为221V,则
var arr1=new byte[]{0x43,0x5D,0x38,0x10};反向排列(arr1);var flt=位转换器.ToSingle(arr1,0)给出了它。所以你可以:
Array.Reverse(resp,3,4);浮动电压=位转换器至单个(分别为3)并且您的IEEE754是big-endian格式。您确定响应告诉您IEEE754中的电压吗?因为207.686将是
9eaf4f43
,所以您可以自己查看它:
Single sing=207.686f;var iee=BitConverter.GetBytes(sing);Console.WriteLine(位转换器.ToString(iee))如果实际结果为221V,则
var arr1=new byte[]{0x43,0x5D,0x38,0x10};反向排列(arr1);var flt=位转换器.ToSingle(arr1,0)给出了它。所以你可以:
Array.Reverse(resp,3,4);浮动电压=位转换器至单个(分别为3)并且你的IEEE754是大端格式的。我认为你是对的,但是看看操作代码。这
float result=BitConverter.ToSingle(BitConverter.IsLittleEndian?data.Reverse().ToArray():数据,0)
也这样做,应该会给出正确的结果……尽管我注意到他是针对所有响应而不是真实数据这样做的:)@Pikoh并且反转整个响应会更改各个字段的开始索引。。。最好是反转需要反转的单个“片段”信息。是的。该过程应首先将响应拆分为不同的部分,然后反转它们并
位转换器。ToSingle
。那应该管用fine@xanatos,你在主要帖子上的评论是对的。。我把所有字节都放入位转换器。我想只取字节[3]-字节[6]。响应发送所有字节,包括,start,datalen,crc,所以我的错误是转换所有字节。你的评论是对的,我想你是对的,但是看看操作码。这
float result=BitConverter.ToSingle(BitConverter.IsLittleEndian?data.Reverse().ToArray():数据,0)
也这样做,应该会给出正确的结果……尽管我注意到他是针对所有响应而不是真实数据这样做的:)@Pikoh并且反转整个响应会更改各个字段的开始索引。。。最好是反转需要反转的单个“片段”信息。是的。该过程应首先将响应拆分为不同的部分,然后反转它们并
位转换器。ToSingle
。那应该管用fine@xanatos,你在主要帖子上的评论是对的。。我把所有字节都放入位转换器。我想只取字节[3]-字节[6]。响应发送所有字节,包括,start,datalen,crc,所以我的错误是转换所有字节。你的评论是对的