BitSet иногда отбрасывает биты

#java #byte #bit

#java #байт #бит

Вопрос:

В настоящее время я пытаюсь прочитать один бит из файла на Java.

Я считываю данные в массив байтов, а затем преобразую массив байтов в набор битов.

Проблема в том, что иногда в преобразованном наборе битов не хватает нескольких битов.

В следующем примере у меня есть 2 байтовых массива, каждый из которых содержит 25 очень похожих байт. Но один преобразуется в ожидаемые 200 бит, а другой — всего в 197 бит, и я понятия не имею, почему.

 import java.nio.ByteBuffer;
import java.util.BitSet;

public class Main {
    public static void main(String[] args) {
        ByteBuffer cb = ByteBuffer.wrap(new byte[] {(byte)0x18,(byte)0x8C,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,});
        BitSet cBits = BitSet.valueOf(cb);
        System.out.println(cBits.length());
        ByteBuffer db = ByteBuffer.wrap(new byte[] {(byte)0x17,(byte)0x8c,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x18,(byte)0x8c,(byte)0x8c,});
        BitSet dBits = BitSet.valueOf(db);
        System.out.println(dBits.length());
    }
}
  

Doodle

Ответ №1:

Длина () набора битов Java является следствием наиболее значимого установленного бита, а не длины массива, который был передан. Это согласуется с описанием bitset как структуры данных, которая увеличивается по мере необходимости — ее логический размер является следствием установленных битов, а не физической емкости некоторого базового буфера.

Возвращает «логический размер» этого набора битов: индекс старшего установленного бита в наборе битов плюс один. Возвращает ноль, если набор битов не содержит установленных битов.

В вашем первом примере самый значимый байт равен 0x18 или двоичному коду 00011000. Три ведущих нулевых бита объясняют расхождение при сравнении со вторым набором битов, самый значимый байт которого равен 0x8c (10001100)

Комментарии:

1. Спасибо. Не ожидал такого странного определения длины, но все же я виноват, что не прочитал документацию.