Java – Convert bytes to unsigned bytes
In Java, byte
is an 8-bit signed (positive and negative) data type, values from -128 (-2^7)
to 127 (2^7-1)
. For unsigned byte
, the allowed values are from 0
to 255
.
Java doesn’t have unsigned bytes (0 to 255). To make an unsigned byte, we can cast the byte
into an int
and mask (bitwise and) the new int
with a 0xff
to get the last 8 bits or prevent sign extension.
byte aByte = -1;
int number = aByte & 0xff; // bytes to unsigned byte in an integer.
Why cast byte to int?
Java uses two’s complement to represent signed numbers (positive and negative), the leftmost bit denotes the sign (0 is positive, 1 is negative), the rest of the bits represents the values from -128 (-2^7)
to 127 (2^7-1)
, the so-called 8-bit byte
only have 7 bits to store the values. The extra values (128 – 255) are unable to fit into a single byte
, and we cast it to a 32-bit unsigned integer for more spaces (bits).
Prerequisite
1. Bytes to Unsigned Byte
1.1 Review the following table for the byte
to unsigned byte (int)
conversion:
Byte | Unsigned Byte |
---|---|
1 | 1 |
2 | 2 |
127 | 127 |
-128 | 128 |
-127 | 129 |
-126 | 130 |
-2 | 254 |
-1 | 255 |
1.2 First, we cast the byte
8-bit into an int
32-bit.
For example, byte -1
in two’s complement, the binary is 1111 1111
.
# two's complement formula to convert positive to negative
# leftmost bit, 1 is negative, 0 is positive
0000 0001 (1)
1111 1110 (invert bits)
1111 1111 (add 1)
1111 1111 (-1)
When we convert or upcast a byte
to an int
, it will increase the bits from 8 to 32. The sign extension will apply and fill in the values of the increased bits.
1111 1111 (-1)
byte -> int
???? ???? | ???? ???? | ???? ???? | 1111 1111
sign extension
1111 1111 | 1111 1111 | 1111 1111 | 1111 1111
1.3 Now, we perform a bitwise and
or &
with a 0xff
to get the last 8 bits.
1111 1111 | 1111 1111 | 1111 1111 | 1111 1111 (int -1)
&
0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 (0xff)
=
0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 (last 8 bits)
1.4 Binary to decimal calculation.
1 1 1 1 1 1 1 1
1, 2, 4, 8, 16, 32, 64, 128 = 255
Done. For -1 , now we have 255.
byte aByte = -1;
int number = aByte & 0xff;
System.out.println(number); // output = 255
2. Java 8
Java 8 introduced many new APIs to support unsigned operations, for byte
, now we have Byte.toUnsignedInt()
to convert a signed byte into an unsigned integer.
package com.mkyong.crypto.bytes;
public class Java8UnsignedByte {
public static void main(String[] args) {
byte aByte = (byte) -2; // -2 (signed) and 254 (unsigned)
System.out.println(aByte); // -2
// Java 8
System.out.println(Byte.toUnsignedInt(aByte)); // 254
}
}
Review the new Byte.toUnsignedInt
; Java 8 uses the same technique to convert a byte to an unsigned integer.
public final class Byte extends Number implements Comparable<Byte> {
/*
@since 1.8
*/
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
3. Old Java + Comments
This Java example is using the same technique, with inline comments. Read for self-explanatory.
package com.mkyong.crypto.bytes;
public class JavaUnsignedByte {
public static void main(String[] args) {
byte input = (byte) -2; // -2 (signed) and 254 (unsigned)
// -2 = 1111 1110 , two's complement
System.out.println("Input : " + input);
// byte (8 bits) cast / widen to int (4 bytes, 16 bits), sign extension will apply
// 1111 1111 | 1111 1111 | 1111 1111 | 1111 1110
int input2 = (int) input;
System.out.println("Input [Binary] : " + Integer.toBinaryString(input2));
// 1111 1111 | 1111 1111 | 1111 1111 | 1111 1110
// &
// 0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 (0xFF) , get last 8 bits
// =============================================
// 0000 0000 | 0000 0000 | 0000 0000 | 1111 1110 unsigned int
int result = input2 & 0xff;
System.out.println(result); // 254
System.out.println(Integer.toBinaryString(result)); // 1111 1110
}
}
“When we convert or upcast a
byte
to anint
, it will increase the bits from 8 to 32. The sign extension will apply and fill in the values of the increased bits.” That’s the moment the penny dropped for me, and the universe made sense again. Thankyou.Thanks. Helped me a lot