5

I'm trying to convert 3 bytes to signed integer (Big-endian) in C#.

I've tried to use BitConverter.ToInt32 method, but my problem is what value should have the lats byte.

Can anybody suggest me how can I do it in different way?

I also need to convert 5 (or 6 or 7) bytes to signed long, is there any general rule how to do it?

Thanks in advance for any help.

2
  • 1
    Sign and Magnitude? Two's complement? Commented Nov 12, 2011 at 12:22
  • It's in two's complement Commented Nov 12, 2011 at 14:38

3 Answers 3

12

As a last resort you could always shift+add yourself:

byte b1, b2, b3;

int r = b1 << 16 | b2 << 8 | b3;

Just swap b1/b2/b3 until you have the desired result.

On second thought, this will never produce negative values.
What result do you want when the msb >= 0x80 ?


Part 2, brute force sign extension:

    private static int Bytes2Int(byte b1, byte b2, byte b3)
    {
        int r = 0;
        byte b0 = 0xff;

        if ((b1 & 0x80) != 0) r |= b0 << 24;
        r |= b1 << 16;
        r |= b2 << 8;
        r |= b3;
        return r;
    }

I've tested this with:

      byte[] bytes = BitConverter.GetBytes(p);
      int r = Bytes2Int(bytes[2], bytes[1], bytes[0]);
      Console.WriteLine("{0} == {1}", p, r);

for several p.

Sign up to request clarification or add additional context in comments.

2 Comments

ok, thank you for help. My finally solution is a bit different, but I also use the checking mechanism of most significant bit (b1 & 0x80) to determine if number is positive or negative.
@vc.one, yes , thank for the edit. The + also needed () : (b1 << 16) + ...
4

The last value should be 0 if it isn't set for a positive number, 256 for a negative.

To know what you should pass in, you can try converting it the other way:

var bytes = BitConverter.GetBytes(i);
int x = BitConverter.ToInt32(bytes, 0);

Comments

1

To add to the existing answers here, there's a bit of a gotcha in that Bitconverter.ToInt32() will throw an ArgumentException if the array is less than sizseof(int) (4) bytes in size;

Destination array is not long enough to copy all the items in the collection. Check array index and length.

Given an array less than sizeof(int) (4) bytes in size, you can compensate for left/right padding like so;

Right-pad

Results in positive Int32 numbers

int intByteSize = sizeof(int);
byte[] padded = new byte[intByteSize];
Array.Copy(sourceBytes, 0, padded, 0, sourceBytes.Length);
sourceBytes = padded;

Left-pad

Results in negative Int32 numbers, assuming non-zero value at byte index sourceBytes.Length - 1.

int intByteSize = sizeof(int);
byte[] padded = new byte[intByteSize];
Array.Copy(sourceBytes, 0, padded, intByteSize - sourceBytes.Length, sourceBytes.Length);
sourceBytes = padded;

Once padded, you can safely call int myValue = BitConverter.ToInt32(sourceBytes, 0);.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.