El almacenamiento de valor int de máscara de bits - extracto 1 bits valoradas
Pregunta
Estoy cálculo de la int equivalente de un conjunto dado de bits y el almacenamiento de que en la memoria. A partir de ahí, me gustaría para determinar todos los bits 1 de valor de la máscara de bits originales. Ejemplo:
33 -> [1,6]
97 -> [1,6,7]
Ideas para una implementación en Java?
Solución
En BitSet
java.util.BitSet
para almacenar, así, un conjunto de bits.
Así es como se puede convertir de un int
a un BitSet
, en base a qué bits en el int
se establece:
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;
}
Así que ahora usted puede hacer lo siguiente:
System.out.println(fromInt(33)); // prints "{0, 5}"
System.out.println(fromInt(97)); // prints "{0, 5, 6}"
Y simplemente para la corrección, aquí está la transformación inversa:
static int toInt(BitSet bs) {
int num = 0;
for (int k = -1; (k = bs.nextSetBit(k + 1)) != -1; ) {
num |= (1 << k);
}
return num;
}
Así que componen los dos juntos, siempre nos dan la espalda al número original:
System.out.println(toInt(fromInt(33))); // prints "33"
System.out.println(toInt(fromInt(97))); // prints "97"
En 0 basada en la indexación
Tenga en cuenta que este usos de indexación basada en 0, que es el más comúnmente utilizado de indexación para los bits (y casi todo lo demás en Java). Esto también es más correcto. En lo que sigue, ^
denota exponenciación:
33 = 2^0 + 2^5 = 1 + 32 97 = 2^0 + 2^5 + 2^6 = 1 + 32 + 64
33 -> {0, 5} 97 -> {0, 5, 6}
Si usted insiste en el uso de la indexación basada en 1, sin embargo, se puede utilizar bs.set(k+1);
y (1 << (k-1))
en los fragmentos anteriores. Yo aconsejaría fuertemente en contra de esta recomendación, sin embargo.
preguntas relacionadas
- ¿Qué hace el operador
^
en Java ? - - en realidad no exponenciación
Otros consejos
Para tocar el violín poco, java.lang.Integer tiene algunos métodos estáticos muy útiles. Prueba este código como base de partida para su problema:
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;
}
Te puede mostrar la aplicación de C #, Java debe ser muy similar.
int value = 33; int index = 1; while (value > 0) { if ((value % 2) == 1) Console.WriteLine(index); index++; value /= 2; }
Si desea obtener una matriz como la que es probable que tengas rizar el número de bits que desea comprobar &
el número entero con un bit desplazado 1 para cada paso.
Algo así como (pseudo):
Init array
mask = 1
for (0 to BitCount):
if Integer & mask
array[] = pos
mask << 1
Una variación de bits crujido sería algo como:
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;
}
Tenga en cuenta que dado que los bits son indexados de 1 a medida que solicitó, bits[0]
se deja sin utilizar.