【问题标题】:c# convert byte array to float and divide them by value [closed]c#将字节数组转换为浮点数并将它们除以值[关闭]
【发布时间】:2012-10-12 01:18:54
【问题描述】:

我有一个接收字节的休闲代码,可能必须执行转换为浮点数并表示其转换后的值:

 public float DecodeFloat(byte[] data)
    {
        float x = data[3]|data[2]<<8|data[1]<<16|data[0]<<24;
        return x;
    }

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

                Vector3 vec,rot;
                float x= DecodeFloat (data);
                float y= DecodeFloat (data + 4);
                float z= DecodeFloat (data + 8);
                float alpha= DecodeFloat (data + 12);
                float theta= DecodeFloat (data +16);
                float phi= DecodeFloat (data+20);

                vec.Set(x,y,z);
                rot.Set (alpha,theta,phi);


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

                // latest UDPpacket
                lastReceivedUDPPacket=x.ToString()+" Packet#: "+count.ToString();
                count = count+1;



            }

请问有没有人给我正确的方法?

【问题讨论】:

  • 请描述输入、想要的输出、当前正在发生什么以及应该发生什么。就目前而言,这不是一个可以回答的问题。
  • @Oded 哦,我不知道 - IMO 的“问题”从代码中相当明显。
  • @Marc - 当然,DecodeFloat 函数也对我大喊“错误”,但我正在努力帮助 OP 如何提出一个好问题......

标签: c# arrays byte converter


【解决方案1】:

给定 4 个字节,如果它是整数数据,您通常只会“移位”(&lt;&lt;)。问题中的代码基本上将数据读取int(通过“shift”),然后将int 转换为float。几乎可以肯定这不是预期的结果。

由于您想将其解释为float,您可能应该使用:

float val = BitConverter.ToSingle(data, offset);

其中 offset 是 data + 4data + 8 等中显示的 0、4、8、12 等。这会将 4 个字节(相对于 offset)视为原始 IEEE 754 浮点数据。例如:

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

请注意,这是对“字节顺序”的假设 - 请参阅 BitConverter.IsLittleEndian


编辑:来自 cmets,听起来数据是 other-endian;试试:

public static float ReadSingleBigEndian(byte[] data, int offset)
{
    if (BitConverter.IsLittleEndian)
    {
        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);
}
public static float ReadSingleLittleEndian(byte[] data, int offset)
{
    if (!BitConverter.IsLittleEndian)
    {
        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);

如果您需要对此进行大规模优化,您还可以使用不安全代码执行一些操作以从移位中构建 int(在移位时选择字节顺序),然​​后执行不安全强制以将 int 作为float;例如(注意我没有在这里检查字节序——它在大字节序的机器上可能会出现异常,但大多数人没有这些):

public static unsafe float ReadSingleBigEndian(byte[] data, int offset)
{
    int i = (data[offset++] << 24) | (data[offset++] << 16) |
            (data[offset++] << 8) | data[offset];
    return *(float*)&i;
}
public static unsafe float ReadSingleBigEndian(byte[] data, int offset)
{
    int i = (data[offset++]) | (data[offset++] << 8) |
            (data[offset++] << 16) | (data[offset] << 24);
    return *(float*)&i;
}

或者更疯狂,CPU 更安全:

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 unsafe float ReadSingle(byte[] data, int offset,
    bool littleEndian)
{
    fixed (byte* ptr = &data[offset])
    {
        if (littleEndian != BitConverter.IsLittleEndian)
        {   // other-endian; swap
            byte b = ptr[0];
            ptr[0] = ptr[3];
            ptr[3] = b;
            b = ptr[1];
            ptr[1] = ptr[2];
            ptr[2] = b;
        }
        return *(float*)ptr;
    }
}

【讨论】:

  • 马克,非常感谢!!!这很有帮助!问题解决了:D
  • 马克,它进行转换,但它显示 5.832204E-42 而不是 36.000。我也试过 array.reverse 它只显示 0。我做错了什么?
  • @user1764781 k;这意味着字节序是向后的。您不想反转整个 data - 只是这 4 个字节;我会更新我的答案,2 秒
猜你喜欢
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
  • 2013-01-07
  • 1970-01-01
相关资源
最近更新 更多