How to Convert Int to Unsigned Byte and Back
A byte is always signed in Java. You may get its unsigned value by binary-anding it with 0xFF, though:
int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
System.out.println(i2); // 234
Except char
, every other numerical data type in Java are signed.
As said in a previous answer, you can get the unsigned value by performing an and
operation with 0xFF
. In this answer, I'm going to explain how it happens.
int i = 234;
byte b = (byte) i;
System.out.println(b); // -22
int i2 = b & 0xFF;
// This is like casting b to int and perform and operation with 0xFF
System.out.println(i2); // 234
If your machine is 32-bit, then the int
data type needs 32-bits to store values. byte
needs only 8-bits.
The int
variable i
is represented in the memory as follows (as a 32-bit integer).
0{24}11101010
Then the byte
variable b
is represented as:
11101010
As byte
s are signed, this value represent -22
. (Search for 2's complement to learn more about how to represent negative integers in memory)
Then if you cast is to int
it will still be -22
because casting preserves the sign of a number.
1{24}11101010
The the casted 32-bit
value of b
perform and
operation with 0xFF
.
1{24}11101010 & 0{24}11111111
=0{24}11101010
Then you get 234
as the answer.
If you just need to convert an expected 8-bit value from a signed int to an unsigned value, you can use simple bit shifting:
int signed = -119; // 11111111 11111111 11111111 10001001
/**
* Use unsigned right shift operator to drop unset bits in positions 8-31
*/
int psuedoUnsigned = (signed << 24) >>> 24; // 00000000 00000000 00000000 10001001 -> 137 base 10
/**
* Convert back to signed by using the sign-extension properties of the right shift operator
*/
int backToSigned = (psuedoUnsigned << 24) >> 24; // back to original bit pattern
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
If using something other than int
as the base type, you'll obviously need to adjust the shift amount: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Also, bear in mind that you can't use byte
type, doing so will result in a signed value as mentioned by other answerers. The smallest primitive type you could use to represent an 8-bit unsigned value would be a short
.
Java 8 provides Byte.toUnsignedInt
to convert byte
to int
by unsigned conversion. In Oracle's JDK this is simply implemented as return ((int) x) & 0xff;
because HotSpot already understands how to optimize this pattern, but it could be intrinsified on other VMs. More importantly, no prior knowledge is needed to understand what a call to toUnsignedInt(foo)
does.
In total, Java 8 provides methods to convert byte
and short
to unsigned int
and long
, and int
to unsigned long
. A method to convert byte
to unsigned short
was deliberately omitted because the JVM only provides arithmetic on int
and long
anyway.
To convert an int back to a byte, just use a cast: (byte)someInt
. The resulting narrowing primitive conversion will discard all but the last 8 bits.