30

I have a byte[] that I've read from a file, and I want to get an int from two bytes in it. Here's an example:

byte[] bytes = new byte[] {(byte)0x00, (byte)0x2F, (byte)0x01, (byte)0x10, (byte)0x6F};
int value = bytes.getInt(2,4); //This method doesn't exist

This should make value equal to 0x0110, or 272 in decimal. But obviously, byte[].getInt() doesn't exist. How can I accomplish this task?

The above array is just an example. Actual values are unknown to me.

2
  • the reason the answers work is that the bytes are promoted to integers in case that's what was causing you trouble understanding. "bytes[2] * 256" doesn't fit in a byte, but it's not an issue because "256" is an integer, etc. Commented Jan 22, 2011 at 16:26
  • 1
    possible duplicate of [Convert 4 bytes to int ](stackoverflow.com/questions/2383265/convert-4-bytes-to-int) Commented Jan 22, 2011 at 16:32

6 Answers 6

51

You should just opt for the simple:

int val = ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff);

You could even write your own helper function getBytesAsWord (byte[] bytes, int start) to give you the functionality if you didn't want the calculations peppering your code but I think that would probably be overkill.

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

2 Comments

Ideally it should be (b1 << 8) | (b2 & 0x00ff) If second byte value is greater than 128, the above conversion gives incorrect value, as java considers the byte as negative int.
Why the 0xff? In other words, what's the difference to bytes[0] << 8 | bytes[1]?
7

Here's a nice simple reliable way.

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4);
    // by choosing big endian, high order bytes must be put
    // to the buffer before low order bytes
    byteBuffer.order(ByteOrder.BIG_ENDIAN);
    // since ints are 4 bytes (32 bit), you need to put all 4, so put 0
    // for the high order bytes
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x01);
    byteBuffer.put((byte)0x10);
    byteBuffer.flip();
    int result = byteBuffer.getInt();

Comments

6

Try:

public static int getInt(byte[] arr, int off) {
  return arr[off]<<8 &0xFF00 | arr[off+1]&0xFF;
} // end of getInt

Your question didn't indicate what the two args (2,4) meant. 2 and 4 don't make sense in your example as indices in the array to find ox01 and 0x10, I guessed you wanted to take two consecutive element, a common thing to do, so I used off and off+1 in my method.

You can't extend the byte[] class in java, so you can't have a method bytes.getInt, so I made a static method that uses the byte[] as the first arg.

The 'trick' to the method is that you bytes are 8 bit signed integers and values over 0x80 are negative and would be sign extended (ie 0xFFFFFF80 when used as an int). That is why the '&0xFF' masking is needed. the '<<8' shifts the more significant byte 8 bits left. The '|' combines the two values -- just as '+' would. The order of the operators is important because << has highest precedence, followed by & followed by | -- thus no parentheses are needed.

1 Comment

Thx for this nice explanation. For the same thing but signed value, I used: return arr[off]<<8 | arr[off+1]&0xFF;
1

Alternatively, you could use:

int val = (bytes[2] << 8) + bytes[3]

1 Comment

No: it will return a negative int if bytes[2] is bigger than 0x7f. The "& 0xff" from paxdiablo's answer is required.
0

You can use ByteBuffer. It has the getInt method you are searching for and many other useful methods

Comments

0

The Google Base16 class is from Guava-14.0.1.

new BigInteger(com.google.common.io.BaseEncoding.base16().encode(bytesParam),16).longValue();

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.