【问题标题】:Convert byte[] to UInt16.将 byte[] 转换为 UInt16。
【发布时间】:2016-09-22 18:47:00
【问题描述】:

我有一个 UInt16 的 2d 数组,我已将其转换为原始字节 - 我想获取这些字节并将它们转换回原始的 2D 数组。我已经设法用一个二维数组来做到这一点,但我不知道如何用 UInt16 做到这一点。

这是我的代码:

UInt16[,] dataArray; 
//This array is populated with this data:
[4 6 2]
[0 2 0]
[1 3 4]

long byteCountUInt16Array = dataArray.GetLength(0) * dataArray.GetLength(1) * sizeof(UInt16);

var bufferUInt16 = new byte[byteCountUInt16Array];
Buffer.BlockCopy(newUint16Array, 0, bufferUInt16, 0, bufferUInt16.Length);


//Here is where I try to convert the values and print them out to see if the values are still the same:

UInt16[] originalUInt16Values = new UInt16[bufferUInt16.Length / 8];
for (int i = 0; i < 5; i++)
{
    originalUInt16Values[i] = BitConverter.ToUInt16(bufferUInt16, i * 8);
    Console.WriteLine("Values: " + originalUInt16Values[i]);
}

打印语句显示的值与原始二维数组不同。我对字节和 UInt16 编码很陌生,所以我在这个过程中学习了大部分内容。

*另外,我知道我的代码的最后一块并没有像原始数组那样将值放入二维数组中——现在我只是想打印出这些值,看看它们是否与原始数据匹配。

【问题讨论】:

  • / 8, * 8- 为什么是 8 而不是 sizeof(UInt16) 是 2?从double 结转 :)

标签: c# arrays byte type-conversion


【解决方案1】:

如果你想要的只是转换 UInt16[,]->Byte, 然后 Byte->UInt16 你可以做另一个块复制,这在运行时非常快,代码应该是这样的:

UInt16[,] dataArray = new UInt16[,] {
    {4, 6, 2},
    {0, 2, 0},
    {1, 3, 4}
};
for (int j = 0; j < 3; j++)
{
    for (int i = 0; i < 3; i++)
    {
        Console.WriteLine("Value[" + i + ", " + j + "] = " + dataArray[j,i]);
    }
}
long byteCountUInt16Array = dataArray.GetLength(0) * dataArray.GetLength(1) * sizeof(UInt16);

var bufferUInt16 = new byte[byteCountUInt16Array];

Buffer.BlockCopy(dataArray, 0, bufferUInt16, 0, bufferUInt16.Length);

//Here is where I try to convert the values and print them out to see if the  values are still the same:

UInt16[] originalUInt16Values = new UInt16[bufferUInt16.Length / 2];
Buffer.BlockCopy(bufferUInt16, 0, originalUInt16Values, 0, BufferUInt16.Length);
for (int i = 0; i < 5; i++)
{
     //originalUInt16Values[i] = BitConverter.ToUInt16(bufferUInt16, i * 8);
     Console.WriteLine("Values---: " + originalUInt16Values[i]);
}

顺便说一句,您只将每个 UInt16 分为两个字节,因此您应该计算新的大小除以 2,而不是 8

【讨论】:

  • 谢谢!完美运行。你知道 byte[] 中是否有任何东西可以告诉我原始二维数组的尺寸?如果我只有字节,那么是否有可能知道它们最初来自二维数组?我为此创建了一个新帖子:stackoverflow.com/questions/39693214/…
【解决方案2】:

程序

    public static void Main(string[] args)
    {
        UInt16[,] dataArray = new ushort[,]{ {4,6,2}, {0,2,0}, {1,3,4}}; 
        //This array is populated with this data:

        long byteCountUInt16Array = dataArray.GetLength(0) * dataArray.GetLength(1) * sizeof(UInt16);

        var byteBuffer = new byte[byteCountUInt16Array];
        Buffer.BlockCopy(dataArray, 0, byteBuffer, 0, byteBuffer.Length);

        for(int i=0; i < byteBuffer.Length; i++) {
            Console.WriteLine("byteBuf[{0}]= {1}", i, byteBuffer[i]);
        }


        Console.WriteLine("Byte buffer len: {0} data array len: {1}", byteBuffer.Length, dataArray.GetLength(0)* dataArray.GetLength(1));
        UInt16[] originalUInt16Values = new UInt16[byteBuffer.Length / 2];
        for (int i = 0; i < byteBuffer.Length; i+=2)
        {
            ushort _a = (ushort)( (byteBuffer[i]) | (byteBuffer[i+1]) << 8);
            originalUInt16Values[i/2] = _a;
            Console.WriteLine("Values: " + originalUInt16Values[i/2]);
        }
    }

输出

byteBuf[0]= 4
byteBuf[1]= 0
byteBuf[2]= 6
byteBuf[3]= 0
byteBuf[4]= 2
byteBuf[5]= 0
byteBuf[6]= 0
byteBuf[7]= 0
byteBuf[8]= 2
byteBuf[9]= 0
byteBuf[10]= 0
byteBuf[11]= 0
byteBuf[12]= 1
byteBuf[13]= 0
byteBuf[14]= 3
byteBuf[15]= 0
byteBuf[16]= 4
byteBuf[17]= 0
Byte buffer len: 18 data array len: 9
Values: 4
Values: 6
Values: 2
Values: 0
Values: 2
Values: 0
Values: 1
Values: 3
Values: 4

您会看到ushort,又名UInt164 = 0x04 0x00 的字节顺序存储,这就是我选择转换公式的原因

            ushort _a = (ushort)( (byteBuffer[i]) | (byteBuffer[i+1]) << 8);

它将在索引i 处获取byte 并在i+1 处获取下一个byte 并将其左移一个字节(8 位)的大小以构成@987654331 的16 位@。换句话说,ushort _a = 0x[second byte] 0x[first byte],然后重复。此转换代码特定于您所在机器的字节序,因此不可移植。

我还修复了 byteBuffer 数组太大的错误,因为它与因子 8 相乘。 ushortbyte 大小的两倍,因此我们只需要数组长度中的因子 2。

【讨论】:

    【解决方案3】:

    解决问题的标题(将字节[] 转换为 UInt16):

    UInt16 result = (UInt16)BitConverter.ToInt16(yourByteArray, startIndex = 0);
    

    【讨论】:

      【解决方案4】:

      你的铸造,所以你应该能够隐含地做事

      var list = new List<byte> { 1, 2 , 
      var uintList = new List<UInt16>();
      
      //Cast in your select
      uintList = list.Select(x => (UInt16)x).ToList();
      

      【讨论】:

        猜你喜欢
        • 2016-10-10
        • 2016-07-04
        • 2011-06-08
        • 1970-01-01
        • 2014-07-21
        • 1970-01-01
        • 2021-06-29
        • 2019-10-13
        • 1970-01-01
        相关资源
        最近更新 更多