Question

I am writing a function short getBits(short data, int p, int n)

I have tried:

public static short getBits(short data, int p, int n) {
    short bitmask = (short) ((~0 << (16 -n)) >>> p);
    short returnVal = (short) ((bitmask & data) >>> (16 - n));
    return returnVal;
}

This works for getBits( (short) 0x7000, 0, 4) but if I were to replace the 7 with an 8 I get a negative value.

Was it helpful?

Solution

There are a few things to remember about java data types, to make this thing work.

I'm assuming you're using int variables because of the absence of explicit casts in your expression. If you're using an int type for your variables: data start_pos, and length; you should be using 32 instead of 16, since int's are 32-bit values.

Also if you're going to use integer primitive types like int, short or byte, remember that these primitive types are two's complement that are sign-extended, meaning that if you do a right shift on negative numbers like ~0 (evaluates to -1), ones will be appended on the higher order bit (sign bit) instead of zeroes.

For instance:

1111 1111 1111 1111 1111 1111 1111 1000        
>>1
1111 1111 1111 1111 1111 1111 1111 1100 

Now going back to your problem. The general idea is to be able to do a:

data & mask

Now, generating the mask is a bit tricky on signed data types. It would make sense to generate the mask using:

(~0 << (32 - length) >> (32 - length - start_pos))

But this won't work of course because of the sign extension.

I would suggest that instead of using right-shift >>, use rotate operator >>> that way instead of ones being appended on the higher order bit, the rotate operator will append the lower order bit.

For instance:

1111 1111 1111 1111 1111 1111 1111 1000        
>>>1
0111 1111 1111 1111 1111 1111 1111 1100 

so...

mask = (~0 << 32-length >>> 32-length-start_pos)

And your final answer would look something like:

(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos

The outermost rotate operation moves your masked data to the lower order bits.

OTHER TIPS

Not sure why you need to use short. Here is a solution using long.

public static long getBits(long data, int p, int n) {
    assert p >= 0 && p < 64;
    assert n >= 0 && n < 64;
    return (data >> p) & ((1 << n) - 1);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top