如何最快地将byte []转换为float []或反之?

4
哪种方法是将byte[]转换为float[]或反之,最快的方式(当然不需要循环)?
我现在正在使用BlockCopy,但需要双倍的内存。我想要一种类似于类型转换的方法。
我需要进行此转换只是为了通过套接字发送数据,并在另一端重构数组。

你的意思是:1字节 => 1浮点数 还是 4字节 => 1浮点数? - user703016
请问您为什么想要这样做,以及您想要用它来做什么?这将使我们更容易提出好的解决方案。回答中提到了许多有趣的技巧,但是根据您实际想要实现的目标,有些可能会达成您想要的结果,而有些则可能不会。 - Erik A. Brandstadmoen
好的!你是对的,我刚刚编辑了问题。 - Pedro77
4个回答

7
当然,msarchet的提议也会进行复制。你说的是改变.NET对内存区域的认知方式,如果不想复制的话。
但是,我认为你想要的不可能实现,因为字节和浮点数在内存中的表示完全不同。一个字节在内存中使用恰好一个字节,而一个浮点数使用4个字节(32位)。
如果你没有足够的内存来存储数据,只需将数据表示为在内存中使用最多的数据类型,并在使用时转换实际使用的值即可。
你打算如何将浮点数(可以表示±1.5×10−45到±3.4×10^38之间的值)转换为字节(可以表示0到255之间的值)?
(有关更多信息,请参见此处:

更多关于.NET中浮点类型的信息在这里:http://csharpindepth.com/Articles/General/FloatingPoint.aspx


那么我猜将它们存储在类似结构体的布局中是最好的,就像Philipp Schmid所建议的那样。关于这个问题的更多讨论请参考这里:http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/60150e7b-665a-49a2-8e2e-2097986142f3 - Erik A. Brandstadmoen

4
您可以使用StructLayout来实现此操作(来自Stack Overflow问题C#不安全值类型数组到字节数组的转换)。
[StructLayout(LayoutKind.Explicit)]
struct UnionArray
{
    [FieldOffset(0)]
    public Byte[] Bytes;

    [FieldOffset(0)]
    public float[] Floats;
}

static void Main(string[] args)
{
    // From bytes to floats - works
    byte[] bytes = { 0, 1, 2, 4, 8, 16, 32, 64 };
    UnionArray arry = new UnionArray { Bytes = bytes };
    for (int i = 0; i < arry.Bytes.Length / 4; i++)
        Console.WriteLine(arry.Floats[i]);
}

0
IEnumerable<float> ToFloats(byte[] bytes)
{
  for(int i = 0; i < bytes.Length; i+=4)
     yield return BitConverter.ToSingle(bytes, i);
}

你正在使用for循环并转换数据,我不想将byte转换为float,我想要类似于*byte = &float[0]的东西。 - Pedro77

-1

如果您可以访问LINQ,则有两种方法:

var floatarray = ByteArry.AsEnumerable.Cast<float>().ToArray();

或者只是使用数组函数

var floatarray = Array.ConvertAll(ByteArray, item => (float)item);

OP说“不要用循环”。你提供的两个选项都有隐藏的循环。第一个实际上有两个循环。而且,也没有一个能像BlockCopy一样被优化。 - Brook
Brook,你是对的。而且这种方法实际上会使用1个loat空间来存储每个字节,这是一种浪费空间的做法,我不需要那样。我只需要进行这种转换以便通过套接字发送并在另一端重构数组。 - Pedro77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接