Хранение значения Bitmask - Extract 1 ценные биты

StackOverflow https://stackoverflow.com/questions/2932712

  •  05-10-2019
  •  | 
  •  

Вопрос

Я вычисляю эквивалент INT данного набора битов и хранение того, что в памяти. Оттуда я хотел бы определить все 1 ценные биты из оригинальной ратушинки. Пример:

33 --> [1,6]
97 --> [1,6,7]

Идеи для реализации в Java?

Это было полезно?

Решение

На BitSet

Использовать java.util.BitSet Хранить, ну, набор битов.

Вот как вы можете конвертировать из int к А. BitSet, на основе которых биты в int устанавливается:

static BitSet fromInt(int num) {
    BitSet bs = new BitSet();
    for (int k = 0; k < Integer.SIZE; k++) {
        if (((num >> k) & 1) == 1) {
            bs.set(k);
        }
    }
    return bs;
}

Так что теперь вы можете сделать следующее:

System.out.println(fromInt(33)); // prints "{0, 5}"
System.out.println(fromInt(97)); // prints "{0, 5, 6}"

И только для полноты, вот обратное преобразование:

static int toInt(BitSet bs) {
    int num = 0;
    for (int k = -1; (k = bs.nextSetBit(k + 1)) != -1; ) {
        num |= (1 << k);
    }
    return num;
}

Так что составляя оба вместе, мы всегда возвращаем первоначальный номер:

System.out.println(toInt(fromInt(33))); // prints "33"
System.out.println(toInt(fromInt(97))); // prints "97"

На 0 на основе индексации

Обратите внимание, что это использует 0 индексацию на основе 0, что является более часто используемой индексацией для битов (и больше всего остального в Java). Это также вернее. В следующих, ^ Обозначает экспоненцию:

33 = 2^0 + 2^5 = 1 + 32          97 = 2^0 + 2^5 + 2^6 = 1 + 32 + 64
33 -> {0, 5}                     97 -> {0, 5, 6}

Если вы настаиваете на использовании 1 индексации на основе 1, вы можете использовать bs.set(k+1); а также (1 << (k-1)) на вышеуказанных фрагментах. Однако я бы сильно посоветовал против этой рекомендации.

Связанные вопросы

Другие советы

Для Bit Hindling Java.lang.integer имеет несколько очень полезных статических методов. Попробуйте этот код в качестве исходной базы для вашей проблемы:

public int[] extractBitNumbers(int value) {
    // determine how many ones are in value
    int bitCount = Integer.bitCount(value);
    // allocate storage
    int[] oneBits = new int[bitCount];
    int putIndex = 0;
    // loop until no more bits are set
    while (value != 0) {
        // find the number of the lowest set bit
        int bitNo = Integer.numberOfTrailingZeros(value);
        // store the bit number in array
        oneBits[putIndex++] = bitNo+1; 
        // clear the bit we just processed from the value
        value &= ~(1 << bitNo);      
    }
    return oneBits;
}

Я могу показать вам реализацию C #, Java должен быть очень похожим.

значение int = 33; int index = 1; в то время как (значение> 0) {if ((значение% 2) == 1) console.writeline (индекс); Индекс ++; значение / = 2; }

Если вы хотите получить массив, который, вероятно, понадобится затереть количество битов, которые вы хотите проверить & Целое число с немного смещенным 1 для каждого шага.

Что-то вроде (псевдо):

Init array
mask = 1
for (0 to BitCount):
  if Integer & mask
    array[] = pos
  mask << 1

Вариация битового хрустящина было бы чем-то вроде:

int[] getBits(int value) {
  int bitValue = 1;
  int index = 1;
  int[] bits = new int[33];

  while (value >= bitValue)
  {
    bits[index++] = (value & bitValue);
    bitValue << 1; // or: bitValue *= 2;
  }
  return bits;
}

Обратите внимание, что поскольку биты проиндексируются из 1, как вы запрашивали, bits[0] остается неиспользованным.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top