Хранение значения Bitmask - Extract 1 ценные биты
Вопрос
Я вычисляю эквивалент 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))
на вышеуказанных фрагментах. Однако я бы сильно посоветовал против этой рекомендации.
Связанные вопросы
- Что это
^
Оператор делает в Java? - это на самом деле не экспоненция
Другие советы
Для 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]
остается неиспользованным.