1

私はバイトを受け取り、おそらくfloatへの変換を実行し、変換された値を表す必要があるコードを持っています:

 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;



            }

私を正しい方法で配置してくれる人はいますか?

4

1 に答える 1

3

4 バイトの<<場合、整数データの場合、通常は「シフト」( ) するだけです。問題のコードは、基本的にデータを として読み取りint(「シフト」を介して)、次に を にキャストintfloatます。これは、ほぼ確実に意図したものではありません。

として解釈したいのでfloat、おそらく次を使用する必要があります。

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

ここで、offset は、 、 などに示されているdata + 40、4、8、12data + 8などです。これは、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


編集:コメントから、データが他のエンディアンのように聞こえます。試す:

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

これを大規模に最適化する必要がある場合は、安全でないコードを使用してintfrom シフト (シフト時にエンディアンを選択) を作成し、安全でない強制を実行して;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;
    }
}
于 2012-10-22T09:00:18.897 に答える