Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Packing two shorts into one int, dealing with negative and positive

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.

like image 706
Caleb Jares Avatar asked May 08 '11 20:05

Caleb Jares


1 Answers

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
    }
like image 102
Ted Hopp Avatar answered Sep 20 '22 07:09

Ted Hopp