【问题标题】:how to convert an array of floats to a byte array? [duplicate]如何将浮点数组转换为字节数组? [复制]
【发布时间】:2012-11-28 08:39:00
【问题描述】:

可能重复:
Convert an array of different value types to a byte array

我有 6 个浮点数,我需要将它们放入浮点数数组中,然后将它们转换为字节。我们开始:

float x= g.transform.position.x;
float y= g.transform.position.y;
float z= g.transform.position.z;
float alpha = g.transform.rotation.eulerAngles.x;
float theta = g.transform.rotation.eulerAngles.y;
float phi =  g.transform.rotation.eulerAngles.z;

将浮点数数组转换为字节数组的最佳方法是什么?

【问题讨论】:

  • 你能多说一下这个目标吗?特别是你想要哪种字节序?
  • @CodesInChaos,目标是将浮点数放入数组,将浮点数数组放入字节数组,然后通过 UDP 以大字节序发送这个字节数组,你知道怎么做吗?

标签: c# arrays floating-point byte converter


【解决方案1】:
byte[] data = new float[]{x,y,z,alpha,theta,phi}
                  .SelectMany(f => BitConverter.GetBytes(f)).ToArray();

或(取决于消费者的计算机架构)

byte[] data = new float[]{x,y,z,alpha,theta,phi}
              .SelectMany(f => BitConverter.GetBytes(f).Reverse()).ToArray();

您可能还想使用BitConverter.IsLittleEndian 来决定选择哪一个作为@CodesInChaos 的建议

【讨论】:

  • 请注意,这使用本地字节序,因此不适合持久存储或网络通信。
  • @CodesInChaos 我已经建议了序列化技术,并在他之前的问题中给 OP 举了一个例子。
  • 如果与小端到大端有关,那就太好了,上面的解决方案显示了一个错误,上面写着 Type float[]' does not contain a definition for SelectMany' and no extension method SelectMany' of type float[] ' 可以找到(您是否缺少 using 指令或程序集引用?)
  • @TimTaker a) 包括命名空间System.Linq b) 你也可以试试BitConverter.GetBytes(f).Reverse() 但我认为你不需要这个.
  • @L.B 你应该在反转之前检查BitConverter.IsLittleEndian,即使.net/mono 通常只在小端平台上运行。
【解决方案2】:

如果本机字节序和 LINQ 是可以接受的,L.B 的答案很好。如果您想要一致的(小)字节序,请使用BinaryWriter

using(var stream = new MemoryStream())
using(var writer = new BinaryWriter(stream))
{
   writer.Write(x);
   writer.Write(y);
   ...
   return stream.ToArray();
}

如果您想使用大字节序,您可以使用以下辅助方法:

byte[] GetBytesBigEndian(float f)
{
  var bytes = BitConverter.GetBytes(f);
  if(BitConverter.IsLittleEndian)
    Array.Reverse(bytes);
  return bytes;
}

using(var stream = new MemoryStream())
using(var writer = new BinaryWriter(stream))
{
   writer.Write(GetBytesBigEndian(x));
   writer.Write(GetBytesBigEndian(y));
   ...
   return stream.ToArray();
}

如果速度太慢,还有一些 unsafe 技巧可以加快速度。

【讨论】:

  • 有没有办法在没有linq的情况下使用这种方法?
  • @TimTaker 添加了一个不依赖 LINQ 的版本。
【解决方案3】:
float[] source = new float[100];
byte[] dest = new byte[source.Length * sizeof(float)];
Buffer.BlockCopy(source, 0, dest, 0, dest.Length);

【讨论】:

    【解决方案4】:

    尝试类似:

    var farray = new float[] {12.4f, 12.3f, 4.5f}; // or what ever values you want.
    var bArray = new byte[farray.Length];
    Buffer.BlockCopy(farray, 0, bArray, 0, bArray.Length);
            foreach (byte value in bArray)
                Console.Write("{0}  ", value);
    

    欲了解更多信息,请访问MSDN

    希望这会有所帮助。

    【讨论】:

    • 可以通过数组列表实现吗?
    【解决方案5】:

    这是一种厚颜无耻的方式:

    float x = 1F;
    float y = 2F;
    float z = 3F;
    float alpha = 4F;
    float theta = 5F;
    float phi = 6F;
    byte[] raw = new byte[6 * sizeof(float)];
    fixed (byte* ptr = raw)
    {
        float* typed = (float*)ptr;
        typed[0] = x;
        typed[1] = y;
        typed[2] = z;
        typed[3] = alpha;
        typed[4] = theta;
        typed[5] = phi;
    }
    return raw;
    

    但是请注意,它对字节顺序做出了假设。您可能需要检查 BitConverter.IsLittleEndian 并在必要时反转每个 4 字节块。

    当然,如果您可以重复使用现有的缓冲区,那就更好了。相同的方法 - 只需传入现有的 byte[] 作为参数,而不是每次都创建一个新参数。

    【讨论】:

    • 哦..对不起,我不能使用不安全的比赛
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多