C# i use Modbus/TCP to get Data, Data type is 「LReal」. i want turn to double

Viewed 44

i use Modbus/TCP to get data, data type is LReal.

but i want LReal to int.

this is my data.

enter image description here

enter image description here

enter image description here

staic_13 data is 「4.232」

but i get [80] 16400 [81]-2098 [82] -9962 [83] -30933.

i don't know how turn to double

1 Answers

Based on this experimental Python code,

>>> x = [16400, -2098, -9962, -30933]
>>> struct.unpack(">d", struct.pack(">4h", *x))
(4.242,)

it looks like you'd need to concatenate those 4 16-byte integers in big-endian format, then interpret those 8 bytes as a single big-endian double.

In .NET 6 (see this fiddle):

using System.Buffers.Binary;
using System;

short[] values = {16400, -2098, -9962, -30933};
byte[] buf = new byte[values.Length * sizeof(short)];
for (int i = 0; i < values.Length; i++)
{
    BinaryPrimitives.WriteInt16BigEndian(buf.AsSpan(i * sizeof(short)), values[i]);
}
double result = BinaryPrimitives.ReadDoubleBigEndian(buf);
Console.WriteLine(result);

In .NET 4 (see this fiddle):

using System;

public class Program
{
    public static void Main()
    {
        short[] values = {16400, -2098, -9962, -30933};
        byte[] buf = new byte[8];
        for (int i = 0; i < 4; i++)
        {
            byte[] sh_buf = BitConverter.GetBytes(values[i]);
            if(BitConverter.IsLittleEndian) {
                // Flip the bytes around if we're little-endian
                buf[(3 - i) * 2] = sh_buf[0];
                buf[(3 - i) * 2 + 1] = sh_buf[1];
            } else {
                buf[i * 2] = sh_buf[0];
                buf[i * 2 + 1] = sh_buf[1];
            }
        }
        double result = BitConverter.ToDouble(buf, 0);
        Console.WriteLine(result);
    }
}
Related