Преобразование значений с плавающей точкой с прямым и обратным порядком байтов с использованием 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);