【问题标题】:How to convert a byte array to double array in C#?如何在 C# 中将字节数组转换为双精度数组?
【发布时间】:2011-10-20 06:47:51
【问题描述】:

我有一个包含双精度值的字节数组。我想将它转换为双数组。在 C# 中可以吗?

字节数组如下:

byte[] bytes; //I receive It from socket

double[] doubles;//I want to extract values to here

我以这种方式创建了一个字节数组(C++):

double *d; //Array of doubles
byte * b = (byte *) d; //Array of bytes which i send over socket

【问题讨论】:

  • 转换很容易,但解释却不容易。你想要哪个?
  • 更好的语言,比如 C++ 或 JavaScript?就这一点,我不回答这个问题。
  • 你会如何在 JavaScript 中做到这一点?
  • 数组中的字节是如何存储的?
  • 你在这里问了一些奇怪的问题......

标签: c# .net bytearray


【解决方案1】:

你不能转换数组类型;但是:

byte[] bytes = ...
double[] values = new double[bytes.Length / 8];
for(int i = 0 ; i < values.Length ; i++)
    values[i] = BitConverter.ToDouble(bytes, i * 8);

或(替代):

byte[] bytes = ...
double[] values = new double[bytes.Length / 8];
Buffer.BlockCopy(bytes, 0, values, 0, values.Length * 8);

应该这样做。您也可以在unsafe 代码中执行此操作:

byte[] bytes = ...
double[] values = new double[bytes.Length / 8];
unsafe
{
    fixed(byte* tmp = bytes)
    fixed(double* dest = values)
    {
        double* source = (double*) tmp;
        for (int i = 0; i < values.Length; i++)
            dest[i] = source[i];
    }
}

我不确定我是否建议这样做

【讨论】:

  • 如果数据是大端的怎么办?
  • @Marc Garvell 我通过 File.ReadAllBytes() API 读取了一个文本文件,然后使用 for 循环我刚刚做了 doubleArray[i] = byteArray[i];循环结束后,数组的内容都相同。是的,数组的大小是 1000 个项目。那么究竟什么时候应该使用 BitConverter?如果上述解决方案有效。
  • @Gabe 确实;那么他们需要处理这个问题;p
  • @zenwalker 我假设数据是 IEEE-754 编码的双精度数,因此双精度数的 1/8 是字节。 doubleArray[i] = byteArray[i]; 做了一些更简单的事情,最终会有很多双精度值在 [0-255] 范围内的整数值
  • @MarcGravell tr​​ue w.r.t 一个字节的范围,但是您还看到它在哪里超出?总是字节限制为 255 对吗?
【解决方案2】:

我将从这里添加对超级不安全代码的引用C# unsafe value type array to byte array conversions

请注意,它基于 C# 的一个未记录的“功能”,所以明天它可能会死。

[StructLayout(LayoutKind.Explicit)]
struct UnionArray
{
    [FieldOffset(0)]
    public byte[] Bytes;

    [FieldOffset(0)]
    public double[] Doubles;
}

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 / 8; i++)
        Console.WriteLine(arry.Doubles[i]);   
}

此方法的唯一优点是它不会真正“复制”数组,因此它在空间和时间上比其他复制数组的方法为 O(n) 的时间为 O(1)。

【讨论】:

  • @MarcGravell Intriguing... 它使用内存页面共享吗?否则不能小于O(n)
  • MSDN 声明“顾名思义,BlockCopy 方法作为一个整体复制一个字节块,而不是一次复制一个字节。” - 但是,它是作为extern 实现的,所以我不能告诉你底层实现是什么。我会想象它调用类似memcpy的东西。
  • @MarcGravell 然后整个操作在空间和时间上是 O(n) (及时因为要复制 n 个字节,你必须复制所有 n 个字节,所以你必须做 n/k操作,其中 是一个常数,是您一次复制的字节数(4 或 8),在空间中,因为您需要分配第二个大小为 n 字节的数组)。显然它比“手动”复制它们更快。我曾希望它使用了写时复制的“肮脏技巧”之一:-)
猜你喜欢
  • 2010-11-21
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 2012-03-07
  • 2015-10-24
  • 1970-01-01
  • 2015-01-13
相关资源
最近更新 更多