Чтение или преобразование в Int32 из двух байтовых массивов - PullRequest
3 голосов
/ 04 сентября 2010

У меня есть 4 байта, которые представляют целое число, хранящееся в 2 отдельных байтовых массивах.Я хотел бы преобразовать их в Int32 БЕЗ копирования в третий байтовый массив и чтения его с использованием потока памяти.

Причина, по которой данные разбиты на два байтовых массива, заключается в том, что это упрощенный пример моей проблемы, которая включаетогромные объемы данных, которые не могут поместиться в один байт.

Есть ли способ достичь этого?Я не хочу объединять два байтовых массива в тройку из-за влияний на производительность, которые важны для меня.

Луна

Ответы [ 5 ]

4 голосов
/ 04 сентября 2010

Вы можете использовать структуру struct вот так

[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;
}

Назначьте свои байты в правильном порядке, затем прочитайте Int32 из iVal;

РЕДАКТИРОВАТЬ: Образец кода

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);
  }
 }
}
1 голос
/ 04 сентября 2010

Вы можете использовать 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 в массиве, вы просто заменяете0 в ToUint16 для изменения положения.

Метод небольшого расширения:

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)
1 голос
/ 04 сентября 2010

Класс BitConverter предназначен для этого:

byte[] parts = { byte1, byte2, byte3, byte4 };
int value = BitConverter.ToInt32(parts, 0);
1 голос
/ 04 сентября 2010

Как то так?

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

Конечно, вы не указали язык, но в этом суть.

0 голосов
/ 04 сентября 2010

Если я правильно понимаю, у вас возникла проблема при чтении через границу двух массивов.Если это так, эта подпрограмма будет читать целое число в любом месте двух массивов, даже если оно пересекает два из них.

    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);
        }
    }

Примечание.изменить порядок копирования байтов.

...