52

Given

private int width = 400; private byte [] data = new byte [2]; 

I want to split the integer "width" into two bytes and load data[0] with the high byte and data[1] with the low byte.

That is binary value of 400 = 1 1001 0000 so data[0] should contain 0000 0001 and data[1] should contain 1001 0000

0

7 Answers 7

97

Using simple bitwise operations:

data[0] = (byte) (width & 0xFF); data[1] = (byte) ((width >> 8) & 0xFF); 

How it works:

  • & 0xFF masks all but the lowest eight bits.
  • >> 8 discards the lowest 8 bits by moving all bits 8 places to the right.
  • The cast to byte is necessary because these bitwise operations work on an int and return an int, which is a bigger data type than byte. The case is safe, since all non-zero bits will fit in the byte. For more information, see Conversions and Promotions.

Edit: Taylor L correctly remarks that though >> works in this case, it may yield incorrect results if you generalize this code to four bytes (since in Java an int is 32 bits). In that case, it's better to use >>> instead of >>. For more information, see the Java tutorial on Bitwise and Bit Shift Operators.

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

7 Comments

>> might not be what you want. >>> doesn't carry the sign bit when you shift so that is probably better to use in this case if you want to capture all 4 bytes.
if I do "new byte[]{width & 0xFF, (width >> 8) & 0xFF}" the compiler says "possible loss of precision required byte found int"
@Kevin: I see I forgot to cast to byte. Will update the answer.
@Taylor: Will check it out, but why is Stephan's code not working?
You don't need the mask, the cast will cut off the excess bits. It doesn't matter whether you use >> or >>>, the ones due to sign extension will be cut off. Though I'd consider >>> better style.
|
13

For converting two bytes the cleanest solution is

data[0] = (byte) width; data[1] = (byte) (width >>> 8); 

For converting an integer to four bytes the code would be

data[0] = (byte) width; data[1] = (byte) (width >>> 8); data[2] = (byte) (width >>> 16); data[3] = (byte) (width >>> 24); 

It doesn't matter whether >> or >>> is used for shifting, any one bits created by sign extension will not end up in the resulting bytes.

See also this answer.

Comments

4

This should do what you want for a 4 byte int. Note, it stores the low byte at offset 0. I'll leave it as an exercise to the reader to order them as needed.

public static byte[] intToBytes(int x) { byte[] bytes = new byte[4]; for (int i = 0; x != 0; i++, x >>>= 8) { bytes[i] = (byte) (x & 0xFF); } return bytes; } 

Comments

1

Integer is 32 bits (=4 bytes) in java, you know?

width & 0xff will give you the first byte, width & 0xff00 >> 8 will give you the second, etc.

Comments

0

To get the high byte, shift right by 8 bits then mask off the top bytes. Similarly, to get the low byte just mask off the top bytes.

data[0] = (width >> 8) & 0xff; data[1] = width & 0xff; 

1 Comment

Apologies - was trying to illustrate the principle, but you're quite right!
0
int width = 400; byte [] data = new byte [2]; data[0] = (byte) ((width & 0xFF00) >> 8); data[1] = (byte) (width & 0xFF); for(int b = 0; b < 2; b++) { System.out.println("printing byte " + b); for(int i = 7; i >= 0; i--) { System.out.println(data[b] & 1); data[b] = (byte) (data[b] >> 1); } } 

Comments

0

I suggest you have a look at the source for HeapByteBuffer. It has the conversion code for all primitive data types. (In fact you could just use a ByteBuffer ;)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.