【问题标题】:How do I convert an array of floats to a byte[] and back?如何将浮点数组转换为 byte[] 并返回?
【发布时间】:2011-06-05 20:47:10
【问题描述】:

我有一个浮点数组,需要转换为字节数组并返回浮点[]...谁能帮我正确地做到这一点?

我正在使用 bitConverter 类,发现自己在尝试追加结果时遇到了困难。

我这样做的原因是我可以将运行时值保存到 IO 流中。目标存储是 Azure Page blobs,以防万一。我不关心它存储在什么字节序中,只要它输入与输出匹配即可。

static  byte[] ConvertFloatToByteArray(float[] floats)
        {
            byte[] ret = new byte[floats.Length * 4];// a single float is 4 bytes/32 bits

            for (int i = 0; i < floats.Length; i++)
            {
               // todo: stuck...I need to append the results to an offset of ret
                ret = BitConverter.GetBytes(floats[i]);

            }
            return ret;
        }


 static  float[] ConvertByteArrayToFloat(byte[] bytes)
{ //to do }

【问题讨论】:

  • 你能处理内存流的序列化/反序列化吗?然后,您可以从流中获取byte 数组或从byte 数组构造流。
  • 使用 .Net 序列化方法?我宁愿不包含任何 XML,而只获取原始位数据……系统已经过优化,每一位都被考虑在内……
  • 你可以做二进制序列化而不是 XML 序列化:msdn.microsoft.com/en-us/library/…
  • @martinho - 据我所知,序列化对象的长度是否与浮点数组的长度完全相同?换句话说,字节偏移量 4 是否总是与传入的 float[3] 值相同,而忽略字节序?没有 XML 垃圾?
  • 它不会包含 XML,但这可能是矫枉过正。我只是提到你可以在没有 XML 的情况下进行序列化。我不确定生成的字节数组会是什么样子,但它可以毫无困难地双向工作。

标签: c# .net floating-point bytearray endianness


【解决方案1】:

如果您正在寻找性能,那么您可以使用Buffer.BlockCopy。既好又简单,而且可能与您在托管代码中获得的速度一样快。

var floatArray1 = new float[] { 123.45f, 123f, 45f, 1.2f, 34.5f };

// create a byte array and copy the floats into it...
var byteArray = new byte[floatArray1.Length * 4];
Buffer.BlockCopy(floatArray1, 0, byteArray, 0, byteArray.Length);

// create a second float array and copy the bytes into it...
var floatArray2 = new float[byteArray.Length / 4];
Buffer.BlockCopy(byteArray, 0, floatArray2, 0, byteArray.Length);

// do we have the same sequence of floats that we started with?
Console.WriteLine(floatArray1.SequenceEqual(floatArray2));    // True

【讨论】:

  • 很棒的解决方案!!!!!!我打算将浮点数乘以 10000000 并移动它,从而失去一些精度。这更好!
  • 您可以使用sizeof(float),而不是文字4
【解决方案2】:

BitConverter.ToSingle(byte[] value, int startIndex) 方法在这里应该会有所帮助。

返回一个单精度浮点数 从四个字节转换的点数 在字节中的指定位置 数组。

您可能想要类似(未经测试)的东西:

static float[] ConvertByteArrayToFloat(byte[] bytes)
{
    if(bytes == null)
        throw new ArgumentNullException("bytes");

   if(bytes.Length % 4 != 0)
        throw new ArgumentException
              ("bytes does not represent a sequence of floats");

    return Enumerable.Range(0, bytes.Length / 4)
                     .Select(i => BitConverter.ToSingle(bytes, i * 4))
                     .ToArray();
}

编辑:非 LINQ:

float[] floats = new float[bytes.Length / 4];

for (int i = 0; i < bytes.Length / 4; i++)
    floats[i] = BitConverter.ToSingle(bytes, i * 4);

return floats;

【讨论】:

  • 我爱 linq,尽管我不明白!这是很多!由于这将是一个关键的性能功能,如果可能的话,我想使用系统级对象。此外,我的 .NET 4 命令行项目中似乎不存在扩展 .ToArray() 。你知道命名空间吗?
  • @makerofthings7:在System.Linq.Enumerable
  • @maker: System.Linq,一如既往。
  • @marthinho 是的,有 System.Linq 但 ToArray() 没有出现。奇数
  • @makerofthings7:我缺少括号(已修复)。那可能是问题所在。现在试试?此外,如果这对性能至关重要,您可能希望使用非 LINQ 版本。简介两者。 :)
【解决方案3】:

当你将 float[i] 复制到字节数组中时,你并没有移动位置,你应该写类似

Array.Copy(BitConverter.GetBytes(float[i]),0,res,i*4);

而不仅仅是:

ret = BitConverter.GetBytes(floats[i]);

反函数遵循相同的策略。

【讨论】:

  • Array.Copy 的最后一个参数是 4。 +1我会将其标记为问题的答案(因为它解决了标题中的问题),但阿尼在他的回答中花了很多时间。反正只有5个点的差距……
【解决方案4】:
static float[] ConvertByteArrayToFloat(byte[] bytes)
{
    if(bytes.Length % 4 != 0) throw new ArgumentException();

    float[] floats = new float[bytes.Length/4];
    for(int i = 0; i < floats.Length; i++)
    {
        floats[i] = BitConverter.ToSingle(bytes, i*4);
    }

    return floats;
}

【讨论】:

    猜你喜欢
    • 2013-01-09
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2011-06-11
    相关资源
    最近更新 更多