我有一个接收字节的代码,可能必须执行转换为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;
}
有没有人以正确的方式把我,请?
答案 0 :(得分:2)
给定4个字节,如果是整数数据,通常只会“移位”(<<
)。问题中的代码基本上将数据作为int
(通过“shift”)读取,然后将int
转换为float
。这几乎肯定不是预期的。
由于您希望将其解释为float
,您应该使用:
float val = BitConverter.ToSingle(data, offset);
其中offset是data + 4
,data + 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);
请注意,这会假设“endianness” - 请参阅BitConverter.IsLittleEndian
。
编辑:从评论中,听起来数据是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
从移位(在移位时选择字节序),然后做一个不安全的强制来获得{{1作为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;
}