3

I need to get unsigned integer from byte array. I understand that java doesn't support unsigned primitives, and I have to use higher primitive (long) to get unsigned int. Many people usually suggest solution like:

public static long getUnsignedInt(byte[] data)
{
    ByteBuffer bb = ByteBuffer.wrap(data);
    bb.order(ByteOrder.LITTLE_ENDIAN);
    return bb.getInt() & 0xffffffffl;
}

But this is not smart since we have to get signed integer then convert it to unsigned which of course may result in overflow exception. I saw other solutions using BigInteger or new java 8 unsigned feature, but I couldn't get it to do what I want.

Anthony J.
  • 375
  • 1
  • 5
  • 14

2 Answers2

3

But this is not smart since we have to get signed integer then convert it to unsigned which of course may result in overflow exception.

There is no such thing as an "overflow exception." Your solution will always work exactly correctly and efficiently. Stop worrying.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • This is obviously the correct answer. However, I'm thinking maybe it should be a comment and the question closed, as it seems entirely based on a misconception. – Harald K Jul 31 '15 at 18:00
1

You could do something like this:

public static long getUnsignedInt(byte[] data) {
    long result = 0;

    for (int i = 0; i < data.length; i++) {
        result += data[i] << 8 * (data.length - 1 - i);
    }
    return result;
}

You basically create an empty long and shift the bytes into it. You can see this in action in the java.io.DataInputStream.readInt() method.

hnefatl
  • 5,860
  • 2
  • 27
  • 49
redxef
  • 492
  • 4
  • 12
  • this will may get a negative result or wrong result if the last byte is larger than 128. – Eki Sep 03 '20 at 07:23
  • @Eki Considering that an int in Java is 32 bits long and we return a long (64 bits) this will not happen unless you try to build an int with 8 bytes, which is nonesense. – redxef Sep 03 '20 at 07:43
  • no, i use a 4 bytes array as input and only last byte has a value larger than 128 and than get a negative output. I think the reason is when you do "result += somebyte", java will convert somebyte into long type implicitly so actually result will plus a negative long value converted by somebyte. – Eki Sep 03 '20 at 09:53
  • Hm, you are right, with unsigned bytes it wouldn't matter (C, etc.). Try doing a bitwise or. – redxef Sep 03 '20 at 10:09