Skip to content
Advertisement

BitSet only grows with true bits and not false?

Currently with Java version “11.0.3” 2019-04-16 LTS on a Linux host (but would expect 8+ compatibility):

in the context of computing a picture in order to send a binary bitmap to some hardware that only knows a 1-bit depth of display, I am using the BitSet for the first time and I get some disappointing results: while populating the Bitset in a loop via the set(int bitIndex, boolean value) method, the resulting ByteArray has not always the same size, which does not suit the hardware that always expect the same 1024 bytes payload.

Here is s SSCCCE that illustrates my problem, the result is when I am trying to set a bit at 0, the structure does not grow. On real data I often get arrays way below the expected 1024 (e.g. 592). What I am missing?

8192 iterations
pixels has size of 1024
8192 iterations
pixels has size of 0    <== WTF?!
8192 iterations
pixels has size of 0    <== WTF?!
import java.util.BitSet;

public class TestBitset {

    public static void main(String[] args){

        BitSet bs = new BitSet();
        int c = 0;
        for (int band = 0; band <= 7; band++) {
            for (int x = 0; x <= 127; x++) {
                for (int bit = 0; bit <= 7; bit++) {
                    boolean val = true;
                    bs.set(band * 128 * 8 + x * 8 + bit, val);
                    c++;
                }
            }
        }
        System.out.println(c + " iterations");
        byte[] pixels = bs.toByteArray();
        System.out.println("pixels has size of " + pixels.length);
        //--------------------------------------------------------
        bs = new BitSet();
        c = 0;
        for (int band = 0; band <= 7; band++) {
            for (int x = 0; x <= 127; x++) {
                for (int bit = 0; bit <= 7; bit++) {
                    boolean val = false;
                    bs.set(band * 128 * 8 + x * 8 + bit, val);
                    c++;
                }
            }
        }
        System.out.println(c + " iterations");
        pixels = bs.toByteArray();
        System.out.println("pixels has size of " + pixels.length);
        //--------------------------------------------------------
        bs = new BitSet(8192);
        c = 0;
        for (int band = 0; band <= 7; band++) {
            for (int x = 0; x <= 127; x++) {
                for (int bit = 0; bit <= 7; bit++) {
                    boolean val = false /*bit % 7 == 1*/;
                    bs.set(band * 128 * 8 + x * 8 + bit, val);
                    c++;
                }
            }
        }
        System.out.println(c + " iterations");
        pixels = bs.toByteArray();
        System.out.println("pixels has size of " + pixels.length);
   }
}

Advertisement

Answer

Quoting the Javadoc of Bitset#toByteArray() for a BitSet s:

Returns a new byte array containing all the bits in this bit set. More precisely,

if byte[] bytes = s.toByteArray();

then bytes.length == (s.length()+7)/8

Note that BitSet#length() is documented as

Returns the “logical size” of this BitSet: the index of the highest set bit in the BitSet plus one. Returns zero if the BitSet contains no set bits.

Now, as all bits in loop 2 and 3 were initialized as false, s.length() = 0 and bytes.length will thus evaluate to 0+7/8 = 0 (int).

Therefore, the observed length of the byte[] in loop 2 and 3 is correct.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement