Bit twiddling in Java: The Unsigned Right Shift Operator

Feb 1, 2011 15:50 · 516 words · 3 minutes read Java

I am currently trying to finish an old Java Project of mine, a powerful Editor for the Casio VZ-1/VZ-10m Synthesizer (a truly wonderful old synth). The synth uses System Exclusive MIDI messages to communicate its settings, and luckily I got hold of the detailled specs for the sysex format. The format often packs two or more values into a single byte (ah, the good ol’ days), so I need to create a lot of bit masks and do bitwise operations.

To make my code better readable, I wanted to create a utility class that gets and sets a given bit range from/into a byte. So I needed to programmatically create bit masks of the form 0...01..10..0, i.e. a block of ones with a specific width starting at a given index.

I pondered a bit about the cleanest way to create those masks and came up with this:

 * @param leftIndex index of the most significant bit of the bit mask
 * @param width width in bits of the mask
 * @return bit mask starting leftIndex bits from the left with width bits set
static int blockMask(int leftIndex, int width) {
    //create a full int of ones,
    //shift it to the right so we have a block of ones 
    //with the desired width, 
    //then shift it left again until it starts where we want it to.
    return (0xFFFFFFFF >>> (32-width)) << (32-leftIndex-width);

My first version of this code used >> which of course did not work: The >> operator preserves the sign of the int it shifts, for example (using only 8 bits for better readability):

11000000 >> 2 = 11110000
01000000 >> 2 = 00010000

Java uses two’s-complement for internal integer representation, so the first bit of an integral type (long, int, short, byte) determines whether the number is positive or negative. When shifting with >>, the bit used for „filling up“ the free bits on the left is the sign bit (the first on the “left” or the most significant bit). This behavior will of course leave the int value 0xFFFFFFFF unchanged, as the operator will fill up the free bits with ones.

The solution was using the >>> operator. I have to admit that after ten years of coding in Java, I had not discovered that one yet. It is different from the >> operator in that it always fills the integral type up with zeros instead of the sign bit. To use the example above:

11000000 >>> 2 = 00110000
01000000 >>> 2 = 00010000

So to create a block of 3 ones, 3 bits from the “left” (i.e. at index 2), you can do the following (again only 8 bits for readability):

//create the block of the desired width
11111111 >>> (8-3)   = 00000111   
//shift it back to the desired position
00000111 << (8-2-3) = 00111000

I admit that there a probably very few cases where you need that special operator, but I must say if you have to extract unsigned int values from raw MIDI Sysex bytes from a 25 year old synth, it sure comes in handy…