8

I'm making a class PackedUnsigned1616 which stores two unsigned shorts in one int, and a class PackedSigned1616 which stores two signed shorts in one int. I've read up on bitwise operations, but I'm still confused on how to deal with signed and unsigned and values that are larger or smaller that a short's range (they are passed in as two ints). Here's what I've got so far:

public final class PackedUnsigned1616 {
public final int field;

private static final int RIGHT = (2 << 15) - 1;
private static final int LEFT = ((2 << 31) - 1) ^ RIGHT;

public PackedUnsigned1616(int left, int right) {
    field = (left << 15) | (right & RIGHT);
}

public int getLeft() {
    return field >> 15;
}
public int getRight() {
    return field & RIGHT;
}

}

This whole concept is confusing me a lot, so if you could shed a little light on it, that would help tremendously.

Caleb Jares
  • 6,163
  • 6
  • 56
  • 83

1 Answers1

11

Interesting way to initialize LEFT and RIGHT. Try this instead:

public final class PackedUnsigned1616 {
    public final int field;
    
    private static final int RIGHT = 0xFFFF;
    
    public PackedUnsigned1616(int left, int right) {
        field = (left << 16) | (right & RIGHT);
    }
    
    public int getLeft() {
        return field >>> 16; // >>> operator 0-fills from left
    }

    public int getRight() {
        return field & RIGHT;
    }
}

For signed values, I think all you need to do is modify getLeft and getRight as follows:

    public int getLeft() {
        return field >> 16; // sign bit is significant
    }

    public int getRight() {
        return (short) (field & RIGHT); // gets cast back to signed int
    }
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • Thanks! But how would I go about making PackedSigned1616? – Caleb Jares May 08 '11 at 20:39
  • @Ted - I've searched for 0xFFFF notation on the internet. Is this hexadecimal? What do the 0x stand for? In addition, the getLeft function for the unsigned version doesn't work. Use the values (5, 32767), it returns 10 and 32727. Same goes for (5, 32766) and (5, 27766) – Caleb Jares May 08 '11 at 20:50
  • 1
    @cable729 - The `0xFFFF` notation is a hex literal. It's defined in the [Java Language Specification](http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.1). As to the code not working, I fixed a bug in my code (which I inherited by copying your code :-0) where it was shifting by **15** instead of 16. Make sure you're using the revised version. – Ted Hopp May 08 '11 at 20:53
  • Yeah I found that too :) Thanks for the help! – Caleb Jares May 08 '11 at 20:56
  • 1
    For signed values you can return a `short` – Peter Lawrey May 08 '11 at 21:05