I want to convert bytes to int in Java. I want to assume bytes to be unsigned bytes. Suppose if
byte a = (byte)0xFF;
int r = (some operation on byte a);
r should be 255 not -1 in decimal.
Then I want to create int value from 3 bytes. Suppose if
byte b1 = (byte)0x0F;
byte b2 = (byte)0xFF;
byte b3 = (byte)0xFF;
int r = (some operation in bytes b1, b2 and b3);
Then r should be 0x000FFFFF
. Byte b1 will be placed at higher 3rd position and byte b3 will be placed at lower 1st position in int value. Also my b1 will range from 0x00 to 0x0F and other bytes will be from 0x00
to 0xFF
, assuming unsigned nature of bytes. If byte b1 is greater than 0x0F, I will extract only lowermost 4 bits. In short I want to extract int from 3 bytes but using only 20 bits of 3 bytes. (total 16 bits from b2 and b3, and 4 lowermost bits from b1). int r must be positive as we are creating from 3 bytes and assuming unsigned nature of bytes.
The intValue() method of Byte class is a built in method in Java which is used to return the value of this Byte object as int.
The int and unsigned int types have a size of four bytes.
So the reason why you are seeing an int as 4 bytes (32 bits), is because the code is compiled to be executed efficiently by a 32-bit CPU. If the same code were compiled for a 16-bit CPU the int may be 16 bits, and on a 64-bit CPU it may be 64 bits.
This is because we have to represent the number 0, so inclusively 0-127 is the other 128 possibilities of our range. If we were only allowing positive values, such as an unsigned byte where negative numbers aren't possible, the range would be 0-255, since these are 256 different values (including the 0).
You have to be careful with the sign-extension here - unfortunately, bytes are signed in Java (as far as I know, this has caused nothing but grief).
So you have to do a bit of masking.
int r = (b3 & 0xFF) | ((b2 & 0xFF) << 8) | ((b1 & 0x0F) << 16);
I would assume you want unsigned byte values
int r = ((b1 & 0xF) << 16) | ((b2 & 0xFF) << 8) | (b3 & 0xFF);
Every byte needs to be masked and shifted to the right bits.
This is pretty easy with bitshifting operators, and binary AND. You want to use only the lower 4 bits of b1, that's exactly what b1 & 0x0F
does. All the rest is shifting the bits to various positions
int r = ( (b1 & 0x0F) << 16) + ((b2 & 0xFF) << 8) + (b3 & 0xFF)
EDIT as @harold pointed out, the former solution (without the 0xFF mask on the lower bytes) would have led to anomalies due to sign extension...
EDIT2 gosh, I always get punched in the face by operator precedence when dealing with these...
Recommended reading:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With