繁体   English   中英

从TWO字节数组读取或转换为Int32

[英]Read or convert to Int32 from TWO byte arrays

我有4个字节表示存储在2个独立字节数组中的整数。 我想将这些转换为Int32而不复制到第三个字节数组并使用memorystream读取它。

数据在两个字节数组之间拆分的原因是因为这是我的问题的一个简化示例,它涉及大量无法放入单个bytearray的数据。

有没有办法实现这个目标? 我不希望将两个字节数组连接成一个thrid,因为性能影响对我来说至关重要。

月亮

您可以使用这样的结构布局

[StructLayout(LayoutKind.Explicit, Size=4)]
struct UnionInt32Value
{
[FieldOffset(0)] public byte byte1;
[FieldOffset(1)] public byte byte2;
[FieldOffset(2)] public byte byte3;
[FieldOffset(3)] public byte byte4;
[FieldOffset(0)] public Int32 iVal;
}

按正确顺序分配字节,然后从iVal读取Int32;

编辑:示例代码

using System;
using System.Runtime.InteropServices;
namespace Test
{
 class Program
 {
  [StructLayout(LayoutKind.Explicit, Size=4)]
  struct UnionInt32Value
  {
   [FieldOffset(0)] public byte byte1;
   [FieldOffset(1)] public byte byte2;
   [FieldOffset(2)] public byte byte3;
   [FieldOffset(3)] public byte byte4;
   [FieldOffset(0)] public Int32 iVal;
  }
  public static void Main(string[] args)
  {
   UnionInt32Value v = new UnionInt32Value();
   v.byte1=1;
   v.byte2=0;
   v.byte3=0;
   v.byte4=0;
   Console.WriteLine("this is one " + v.iVal);

   v.byte1=0xff;
   v.byte2=0xff;
   v.byte3=0xff;
   v.byte4=0xff;
   Console.WriteLine("this is minus one " + v.iVal);

   Console.Write("Press any key to continue . . . ");
   Console.ReadKey(true);
  }
 }
}

像这样的东西?

int x = (array1[index] << 16) + array2[index];

当然,你没有指定一种语言,但这就是它的要点。

BitConverter类适用于此:

byte[] parts = { byte1, byte2, byte3, byte4 };
int value = BitConverter.ToInt32(parts, 0);

您可以使用BitConverter两次,例如:

byte[] bytes0 = new byte[] { 255, 255 };
byte[] bytes1 = new byte[] { 0, 0 };

int res = BitConverter.ToInt16(bytes0, 0) << 16;
res |= BitConverter.ToUInt16(bytes1, 0);

产量-65536 (0b11111111 11111111 00000000 00000000)

如果整数部分不在数组中的位置0,则只需替换ToUint160即可更改位置。

小扩展方法:

public static class BitConverterExt
{
    public static int ToInt32(byte[] arr0, int index0, byte[] arr1, int index1)
    {
        int partRes = BitConverter.ToInt16(arr1, index1) << 16;
        return partRes | BitConverter.ToUInt16(arr0, index0);
    }
}

用法:

byte[] bytes0 = new byte[] { 0x0, 0xA };
byte[] bytes1 = new byte[] { 0x64, 0xFF };

int res = BitConverterExt.ToInt32(bytes0, 0, bytes1, 0);

//Res -10221056 (0xFF640A00)

如果我理解正确,那么在读取两个数组的边界时遇到问题。 如果是这样的话,这个例程将读取两个数组中任何位置的整数,即使它跨越两个数组。

    int ReadInteger(byte[] array1, byte[] array2, int offset)
    {
        if (offset < 0 || (offset + 4) > (array1.Length + array2.Length))
            throw new ArgumentOutOfRangeException();

        if (offset <= (array1.Length - 4))
            return BitConverter.ToInt32(array1, offset);
        else if (offset >= array1.Length)
            return BitConverter.ToInt32(array2, offset - array1.Length);
        else
        {
            var buffer = new byte[4];
            var numFirst = array1.Length - offset;

            Array.Copy(array1, offset, buffer, 0,        numFirst);
            Array.Copy(array2, 0,      buffer, numFirst, 4 - numFirst);

            return BitConverter.ToInt32(buffer, 0);
        }
    }

注意:根据整数的存储方式,您可能希望更改复制字节的顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM