开发者

Read or convert to Int32 from TWO byte arrays

I have the 4 bytes that represent an integer stored in 2 separate byte arrays. I would like to convert these into an Int32 WITHOUT copying to a third byte array and reading that using memorystream.

The reason the data is split across two byte arrays is because this is a simplified example of my issue which involves huge amounts of data that cannot fit into a single bytearray.

Is there any way to achieve this? I开发者_运维技巧 do not wish to concatenate the two byte arrays into a thrid because of the performance implications which are critical to me.

Moon


You can use a struct layout like this

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

Assign your bytes in the correct order then read your Int32 from iVal;

EDIT: Sample code

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


Something like this?

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

Of course, you didn't specify a language, but that's the gist of it.


The BitConverter class is intended for this:

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


You can use BitConverter twice, like:

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

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

Which yields -65536 (0b11111111 11111111 00000000 00000000)

If your integer parts isn't at position 0 in the array, you just replace the 0 in ToUint16 to change the position.

Little extension method:

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

Usage:

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

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

//Res -10221056 (0xFF640A00)


If I understand correctly, you are having a problem whilst reading across the boundary of the two arrays. If that is so, this routine will read an integer anywhere in the two arrays, even if it is across the two of them.

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

Note: depending on how your integers are stored, you might want to change the order in which bytes are copied.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜