使用C#转换大端的浮动值,以小尾数 [英] Converting float values of big endian to little endian using C#

查看:339
本文介绍了使用C#转换大端的浮动值,以小尾数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能从花车大转换为小端?我有一个从大端平台,我通过 UDP 以Windows进程发送一个值(< A HREF =htt​​ps://en.wikipedia.org/wiki/Endianness相对=nofollow>小尾数)。这个值是一个浮动,但是当我试图BitConverter.ToSingle我总是5.832204E-42,但它应该是36.000。

我在做什么错了?

下面是一个剪断code:

  //接收线程
私人无效receiveData的()
{
    诠释计数= 0;    IPEndPoint REMOTEIP =新IPEndPoint(IPAddress.Parse(10.0.2.213),端口);
    客户端=新的UdpClient(REMOTEIP);
    而(真)
    {
        尝试
        {
            IPEndPoint anyIP =新IPEndPoint(IPAddress.Any,0);
            字节[]数据= client.Receive(REF anyIP);            浮X = BitConverter.ToSingle(数据,0);
            浮Y = BitConverter.ToSingle(数据,4);
            浮Z = BitConverter.ToSingle(数据,8);
            浮阿尔法= BitConverter.ToSingle(数据,12);
            浮THETA = BitConverter.ToSingle(数据,16);
            浮法披= BitConverter.ToSingle(数据,20);            打印(&GT;&gt;中+ x.ToString()+,+ y.ToString()+,+ z.ToString()+,+
                  alpha.ToString()+,+ theta.ToString()+,+ phi.ToString());            //最新UDP包
            lastReceivedUDPPacket = x.ToString()+数据包#:+ count.ToString();
            数=计+ 1;
        }


解决方案

36.0和5.832204E-42是尾数对立的,所以这是一个字节序的问题。在Windows / .NET,你通常都是小端的,所以我猜的数据是大​​端。这意味着你需要扭转的数据的每个值,分别的(不是整个数组)。在一个方式,是CPU安全写这个,最好的选择是检查 BitConverter.IsLittleEndian ,并赔偿必要的时候。例如:

 公共静态浮动ReadSingleBigEndian(字节[]的数据,诠释偏移)
{
    返回ReadSingle(数据,偏移,FALSE);
}
公共静态浮动ReadSingleLittleEndian(字节[]的数据,诠释偏移)
{
    返回ReadSingle(数据,偏移,真);
}
私有静态浮动ReadSingle(字节[]的数据,诠释抵消,布尔littleEndian)
{
    如果(BitConverter.IsLittleEndian!= littleEndian)
    {//其他端;反转数据的该部分(4字节)
        字节TMP =数据[偏移]
        数据[偏移] =数据[偏移+ 3];
        数据[偏移+ 3] = TMP;
        TMP =数据[偏移+ 1];
        数据[偏移+ 1] =数据[偏移+ 2];
        数据[偏移+ 2] = tmp目录;
    }
    返回BitConverter.ToSingle(数据,偏移量);
}

 浮动X = ReadSingleBigEndian(数据,0);
浮Y = ReadSingleBigEndian(数据,4);
浮Z = ReadSingleBigEndian(数据,8);
浮阿尔法= ReadSingleBigEndian(数据,12);
浮THETA = ReadSingleBigEndian(数据,16);
浮法披= ReadSingleBigEndian(数据,20);

Is it possible to convert floats from big to little endian? I have a value from a big endian platform that I am sending via UDP to a Windows process (little endian). This value is a float, but when I am trying BitConverter.ToSingle I always get 5.832204E-42, but it should be 36.000.

What am I doing wrong?

Here is a code snipped:

// 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;
        }

解决方案

36.0 and 5.832204E-42 are endian-opposites, so this is an endianness problem. On Windows / .NET, you are usually little-endian, so I'm guessing the data is big-endian. That means you need to reverse the data for each value, separately (not the entire array). To write this in a way that is CPU-safe, the best option is to check BitConverter.IsLittleEndian, and compensate when necessary. For example:

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);
}

with:

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);

这篇关于使用C#转换大端的浮动值,以小尾数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆