0

I'm attempting to make a method that does a left shift with wrap around in Java using BitSet, but I cannot figure out how to get it to do the wrap around. Right now my method just removes the first bit and keeps the rest without adding that first bit to the end.

public static BitSet leftShift(int amount, BitSet b){
    BitSet bit2 = new BitSet(b.length());

    for(int i = b.length(); i > 0; i--){
        bit2.set((i-amount)%b.length(), b.get(i));
    }
    return bit2;
}
Misha
  • 27,433
  • 6
  • 62
  • 78
  • By "left shift" do you mean shift toward the more significant or less significant bits? Your code appears to be trying to shift toward less significant, which would normally be called a right shift. – Misha May 13 '16 at 00:30
  • Shift to the less significant bits. So 11011 would be 10111 with one shift to the left. – user3614496 May 13 '16 at 00:39

1 Answers1

2

Your have 2 problems in your code.

  1. off-by-one error in your loop boundaries. BitSet index is zero-based. So you should start with b.length() - 1 and count to i >= 0 or better yet don't try to be unconventional and instead do the usual for (int i = 0; i < b.length(); i++)
  2. Your index calculation does not wrap around with the negative numbers. An easy way to fix it is to add b.length() before modulo: (i + b.length() - amount) % b.length()

Finally, while it's not a bug, the usual way to iterate over a BitSet is to use nextSetBit rather than going over all indexes.

Taken together, it will looks like this:

BitSet result = new BitSet(b.length());

for (int i = b.nextSetBit(0); i != -1; i = b.nextSetBit(i + 1)) {
    int j = (i + b.length() - amount) % b.length();  // new index after wrapping
    result.set(j);
}
return result;
Misha
  • 27,433
  • 6
  • 62
  • 78
  • Okay so I tried what you gave me and it gives the correct left shift for C1 but not D1. – user3614496 May 13 '16 at 00:49
  • C:1111000011001100101010101111 D:0101010101100110011110001111 C1:1110000110011001010101011111 D1:101010101100110011110001111 – user3614496 May 13 '16 at 00:49
  • It seems to be the b.nextSetBit(0); which fails on D1 because the first bit is not a 1, and therefore it skips it completely. – user3614496 May 13 '16 at 00:57
  • How are you getting those string representations with zeroes and ones? You probably have a bug there. The program I posted works correctly on the input you specified. – Misha May 13 '16 at 01:02
  • I simply call this for loop. for (int i = 0; i < d1.length(); i++) { if (d1.get(i)) { System.out.print("1"); } else { System.out.print("0"); } } – user3614496 May 13 '16 at 01:08
  • `length()` return the index of the highest set bit. Any zeroes after the last one are ignored by `length`. – Misha May 13 '16 at 01:43