Question

I am in the process of writing my own Integer Wrapper class that extends Number. I believe that I have most the functionality implemented. At the moment I am using bit-level operations.

Questions

  1. Am I doing anything that could pose a problem or conflicts with the Number class?

  2. I noticed that Number creates an immutable integer under the covers, but I want to be able to manipulate my underlying integer. Is this a bad idea?

  3. How should I handle negatives integers? I need this to be an unsigned-integer, so I will only be able to store up to 31 bits reliably. Can I store all 32 and treat it as an unsigned or will I have to use a long as my value under the covers?

  4. Should I throw an error if the user passes a negative number to the constructor or should I just set the value to zero?

    this.value = value > 0 ? extractLowerBits(value) : 0;

Here is my Integer Wrapper:

NBitUInteger.java

public final class NBitUInteger extends Number implements
        Comparable<NBitUInteger> {

    private static final long serialVersionUID = 1L;
    private int value;
    private final int bits;
    private final int bitMask;

    public static final int MIN_VALUE = 0x0;
    public static final int MAX_VALUE = 0x7fffffff;

    public NBitUInteger() {
        this(0);
    }

    public NBitUInteger(int value) {
        this(value, 32);
    }

    public NBitUInteger(int value, int bits) {
        this.bits = bits;
        this.bitMask = bitMask(bits);
        this.value = extractLowerBits(value);
    }

    private final int extractLowerBits(final int value) {
        return value & bitMask;
    }

    public int bitMask() {
        return this.bitMask;
    }

    public int bits() {
        return this.bits;
    }

    @Override
    public int intValue() {
        return this.value;
    }

    @Override
    public long longValue() {
        return (long) this.value;
    }

    @Override
    public float floatValue() {
        return (float) this.value;
    }

    @Override
    public double doubleValue() {
        return (double) this.value;
    }

    @Override
    public int compareTo(NBitUInteger other) {
        return compare(this.value, other.value);
    }

    public static final int compare(final int x, final int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

    public final NBitUInteger shiftRight(final int amount) {
        this.value = this.value >> amount;

        return this;
    }

    public final NBitUInteger shiftRight() {
        return shiftRight(1);
    }

    public final NBitUInteger shiftRightPrependBit(final int bit) {
        this.value = (bit << (bits - 1)) | shiftRight().intValue();

        return this;
    }

    public final NBitUInteger shiftLeft(final int amount) {
        this.value = (this.value << amount) & bitMask;

        return this;
    }

    public final NBitUInteger shiftLeft() {
        return shiftLeft(1);
    }

    public final NBitUInteger shiftLeftAppendBit(final int bit) {
        this.value = shiftLeft().intValue() | bit;

        return this;
    }

    public final String toBinaryString() {
        return toBinaryString(this.value, this.bits);
    }

    public static final String toBinaryString(int value, int bits) {
        StringBuilder binStr = new StringBuilder(Integer.toBinaryString(value));

        while (binStr.length() < bits)
            binStr.insert(0, '0');

        return binStr.toString();
    }

    public static final int bitMask(final int bits) {
        return (1 << bits) - 1;
    }
}

Test

public class NBitUIntegerTest {
    public static void main(String[] args) {
        NBitUInteger x = new NBitUInteger(13, 4);
        printResult(x, 13);

        x.shiftRight().shiftRight().shiftRight();
        printResult(x, 1);

        x.shiftLeft(2);
        printResult(x, 4);

        x.shiftLeftAppendBit(1).shiftLeftAppendBit(1).shiftLeftAppendBit(1);
        printResult(x, 7);

        x.shiftRightPrependBit(1);
        printResult(x, 11);
    }

    public static void printResult(NBitUInteger value, int expected) {
        System.out.printf("%s == %s => %b\n",
            value.toBinaryString(),
            NBitUInteger.toBinaryString(expected, value.bits()),
            (value.intValue() == expected));
    }
}

Output

1101 == 1101 => true
0001 == 0001 => true
0100 == 0100 => true
0111 == 0111 => true
1011 == 1011 => true

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top