0

I'm trying to convert my code from using bitwise operations on Long type to the same operations on a BitSet, but I can't find the right syntax.

This is the original code:

public class BitwiseOperationsWithLong {

    private static final long SETS_OF_BITS_LONG = 141655L;

    //...

    private static int calculate(long setsOfBits) {       
        int counter = 0;
        for (int i = 0; i < 10; i++) {
            boolean result = ((1L << i) & SETS_OF_BITS_IN_LONG) != 0L;
            if (result) {
                counter++; 
            }  
    }
    
    return counter;        
}

And this how I try to convert to BitSet:

public class BitwiseOperationsWithBitSet {
    
    private static final String SETS_OF_BITS_STRING = "100010100101010111";
    private static BitSet SETS_OF_BITS_BITSET = bitSetFromString(SETS_OF_BITS_STRING);    

    //...
        
    private static int calculate(BitSet setsOfBits) {       
        int counter = 0;
        for (int i = 0; i < 10; i++) {
            //the line below is the problematic one
            boolean result = ((1 << i).and(SETS_OF_BITS_IN_LONG)) != 0;
            if (result)
                counter++;   
        }
        
        return counter;        ​
   ​}

    //method that sets BitSet from String of bits
    private static BitSet bitSetFromString(String binary) {
        BitSet bitset = new BitSet(binary.length());
        for (int i = 0; i < binary.length(); i++) {
            if (binary.charAt(i) == '1') {
                bitset.set(i);
            }
        }
        return bitset;
    }
}

I can't find the right syntax for this line:

boolean result = ((1 << i).and(SETS_OF_BITS_IN_LONG)) != 0;

I did manage to use the and syntax (instead of &), but I can't find out how to convert the left shift operation part to BitSet. (I am getting The operator & is undefined for the argument type(s) int, BitSet)

pileup
  • 1
  • 2
  • 18
  • 45
  • 1
    Why not just do `Long.countBits(SETS_OF_BITS_IN_LONG)`, and the corresponding thing with `BitSet`? – Andy Turner Oct 22 '21 at 06:50
  • 1
    (btw, you don't seem to use the method parameter) – Andy Turner Oct 22 '21 at 06:51
  • Thank you! It's a simplified version of my code, I don't really do this calculation in the real program, I just had to shorten it for the sake of simplicity and focus on the line with the bitwise operations. Which method parameter? – pileup Oct 22 '21 at 06:53
  • 1
    `calculate(long setsOfBits)` – Andy Turner Oct 22 '21 at 07:43
  • Oops, good catch, I edited the post and it's now `BitSet setsOfBits` (The method itself is called from a part of the code that's not here) – pileup Oct 22 '21 at 07:45
  • 1
    You still don't use `setsOfBits`, in either the `long` or `BitSet` forms. You compare against the bits in `SETS_OF_BITS_IN_LONG`. – Andy Turner Oct 22 '21 at 08:39
  • Oh!! Ok it's my mistake, when I tried to create a sample from my code, I didn't do it correctly. In the real code, I don't compare against `SETS_OF_BITS_IN_LONG`, but against another modified expression but it's not in this part of the code. I need to edit it more properly – pileup Oct 22 '21 at 08:43

1 Answers1

1

When using BitSet you don't need to do the shifting and &ing yourself - the BitSet class has methods for this.

Also you could initialize your BitSet directly from a long constant.

Taking this together your code can look like this:

import java.util.BitSet;

public class BitwiseOperationsWithBitSet {

    private static final long SETS_OF_BITS_LONG = 141655L;
    private static BitSet SETS_OF_BITS_BITSET = BitSet.valueOf(new long[]{SETS_OF_BITS_LONG});

    private static int calculate(BitSet setsOfBits) {       
        int counter = 0;
        for (int i = 0; i < 10; i++) {
            boolean result = setsOfBits.get(i);
            if (result)
                counter++;   
        }
        
        return counter;
    }
}
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • Oh you're right! Btw, I converted from Long to BitSet especially because I am using arrays of bits longer than 64 bits, thus I can't use long this way, I think? If so, I should leave my bit setting method as is? – pileup Oct 22 '21 at 07:21
  • 1
    Your `bitSetFromString()` looks good for the case where you have an array of bits to start with - under the assumption that it is ok that the lowest bit (bit 0) is on the left of your bitstring (the "normal" convention when writing binary numbers is that the lowest bit is on the right.) – Thomas Kläger Oct 22 '21 at 07:34
  • Thank you. If I always work with the String that I declared at the top (`private static final String SETS_OF_BITS_STRING = "100010100101010111";`) then I should not have a problem right? (Regarding what you said about having an array of bits to start with). About the lowest bits, I used the code from the following post: https://stackoverflow.com/questions/33383294/large-string-of-1-and-0-to-bitset and in the answer there, there is also `r-l orientation` - that's the correct one then, right? – pileup Oct 22 '21 at 07:38
  • 1
    @LesserFlow if you have full control over the String of bits (i.e. you create it and you consume it) you will have no problems. If you exchange the String of bits with others (programs or humans) then it might be easier to use the more convential `r-l orientation` because that matches how we write numbers (201 decimal means "two hundred and one", "1101" binary usually means 13 decimal in r-l, but would mean 11 decimal in l-r) – Thomas Kläger Oct 22 '21 at 07:50