You are currently browsing the daily archive for October 7, 2006.

Convert an UNSIGNED byte to a JAVA type
In JAVA, a byte always considered as signed when converted to another type. We must mask the sign bit to JAVA, cast to an integer and process the masked bit if needed. The following method implements this idea :

public class UnsignedByte {

    public static void main (String args[]) {

        byte b1 = 127;

        byte b2 = -128;

        byte b3 = -1;        System.out.println(b1); //127

        System.out.println(b2); //-128

        System.out.println(b3); //-1

        System.out.println(unsignedByteToInt(b1)); //127

        System.out.println(unsignedByteToInt(b2)); //128

        System.out.println(unsignedByteToInt(b3)); //255


   public static int unsignedByteToInt(byte b) {

        return (int) b & 0xFF;



Therefore for an array of 4 bytes (buf[]), which represents an integer :
int i = 0;

int pos = 0;

i += unsignedByteToInt(buf[pos++]) << 24;

i += unsignedByteToInt(buf[pos++]) << 16;

i += unsignedByteToInt(buf[pos++]) << 8;

i += unsignedByteToInt(buf[pos++]) << 0;To convert a byte to it's hexadecimal equivalent

public static String byteToHex(byte b){

    int i = b & 0xFF;

    return Integer.toHexString(i);


The wacky thing about Java is that bytes, shorts, ints, and longs are all signed. Thus, the code:

byte b = 0xAA;

will generate an error (rather than a warning):
possible loss of precision
found : int
required: byte
byte b = 0xAA;

More’s the bummer, there’s no unsigned keyword in Java.
This is obviously of great consternation and gnashing of teeth to C/C++ programmers who are used to reading in files as streams of unsigned bytes, or generating unsigned bytes, or saving space by using unsigned bytes.

In the Java Virtual Machine, bytes, shorts and ints are all four bytes long. Hence, when you add two bytes together you are actually performing 32-bit arithmatic. And when you store the result back into a byte, you’re not even lopping off the high 24 bits — because the number is signed, and you need to retain the sign bit.

Believe it or not, the best way to represent an unsigned byte is to use a signed integer (not that there’s any other kind of integer). Because the Java VM represents bytes as 32 bits, you’re not saving anything by using a byte. And then you really can initialize your “unsigned byte” to a value greater than 0x7F, and you can read in an unsigned byte stream using integers (since the read method returns an int and not a byte).

You can do all your byte arithmetic (+,-,/,*,%) on the integers and the result will come out the same (but you should logical-and (&) with 0xFF to get your “real” unsigned byte). All of your logical operators (&,|) will work, too, since 0xAA as an unsigned byte is stored as 0x000000AA as a signed integer.

Your shift operators (<<,>>,>>>) will also work as expected, except you have to be a little careful. You should logical-and with 0xFF for the result after a left shift, since 0xFF < 1 == 0x1FE, not 0xFE. Thus (0xFF << 1) >> 1 == 0xFF, not 0x7F.

You will not be clever by converting 0xFF to a byte first (either through a typecast or through a byte variable), and then shifting left by 1. The signed byte 0xFF is really -1 (integer 0xFFFFFFFF). The result of the shift will be 0xFFFFFFFE, courtesy of the Java VM’s sign-exteded 32-bit bytes.

public class UnsignedByte { 
    public static void main(String[] args) { 
        byte b = -1; // signedByte = -1, unsignedByte = 255    

        int i = b & 0xFF; // unsignedInt = signedByte & 0xFF; 
        b = (byte) i; // signedByte = (byte) unsignedInt; 
        System.out.println(b);   //-1 
        System.out.println(i);    //255