Wednesday, December 10, 2008

Compensating for lack of unsigned types in Java

For some reason Java has no unsigned primitive types, which makes it really limiting when writing network code or doing bit manipulation.

One workaround is to cast to a longer-type and mask out significant bits.

E.g.:

byte b = getAByte(); // Get a byte from somewhere
int wrong = (int) b;
int right = (int) b & 0xff;

Int wrong will work most of the time, except when you have most-significant bit of the byte set. Because in Java most-significant bit holds the sign, the following happens:

byte b = getAByte(); // let's say this holds 0xff
int wrong = (int) b; // becomes -127 or -0x7f
int right = (int) b & 0xff; // becomes 255 or 0xff

In fact the Java compiler checks this so the following assignments would show compile errors:

byte wrong = 0xff;
byte wrong = 0x80;
byte right = 0x7f;

No comments: