簡體   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