Преобразование значений с плавающей точкой с прямым и обратным порядком байтов с использованием C#

Можно ли преобразовать числа с плавающей точкой в ​​младшую? У меня есть значение от платформы с прямым порядком байтов, которую я отправляю через UDP процессу Windows ( little-endian). Это значение является плавающим, но когда я пытаюсь использовать BitConverter.ToSingle, я всегда получаю 5.832204E-42, но оно должно быть 36.000.

Что я делаю неправильно?

Вот фрагмент кода:

// Receive thread
private void ReceiveData()
{
    int count = 0;

    IPEndPoint remoteIP = new IPEndPoint(IPAddress.Parse("10.0.2.213"), port);
    client = new UdpClient(remoteIP);
    while (true)
    {
        try
        {
            IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = client.Receive(ref anyIP);

            float x = BitConverter.ToSingle(data, 0);
            float y = BitConverter.ToSingle(data, 4);
            float z = BitConverter.ToSingle(data, 8);
            float alpha = BitConverter.ToSingle (data, 12);
            float theta = BitConverter.ToSingle (data, 16);
            float phi = BitConverter.ToSingle (data, 20);

            print(">> " + x.ToString() + ", "+ y.ToString() + ", "+ z.ToString() + ", " +
                  alpha.ToString() + ", "+ theta.ToString() + ", "+ phi.ToString());

            // Latest UDP packet
            lastReceivedUDPPacket=x.ToString()+" Packet#: "+count.ToString();
            count = count+1;
        }

1 ответ

Решение

36.0 и 5.832204E-42 являются противоположностями с прямым порядком байтов, так что это проблема с порядком байтов. В Windows / .NET вы, как правило, имеете младший порядок байтов, так что я предполагаю, что данные имеют порядок байтов. Это означает, что вам нужно обратить данные для каждого значения отдельно (не весь массив).

Чтобы написать это способом, безопасным для ЦП, лучше всего проверить BitConverter.IsLittleEndianи компенсировать при необходимости. Например:

public static float ReadSingleBigEndian(byte[] data, int offset)
{
    return ReadSingle(data, offset, false);
}
public static float ReadSingleLittleEndian(byte[] data, int offset)
{
    return ReadSingle(data, offset, true);
}
private static float ReadSingle(byte[] data, int offset, bool littleEndian)
{
    if (BitConverter.IsLittleEndian != littleEndian)
    {   // other-endian; reverse this portion of the data (4 bytes)
        byte tmp = data[offset];
        data[offset] = data[offset + 3];
        data[offset + 3] = tmp;
        tmp = data[offset + 1];
        data[offset + 1] = data[offset + 2];
        data[offset + 2] = tmp;
    }
    return BitConverter.ToSingle(data, offset);
}

с:

float x= ReadSingleBigEndian(data, 0);
float y= ReadSingleBigEndian(data, 4);
float z= ReadSingleBigEndian(data, 8);
float alpha= ReadSingleBigEndian(data, 12);
float theta= ReadSingleBigEndian(data, 16);
float phi= ReadSingleBigEndian(data, 20);
Другие вопросы по тегам