El almacenamiento de valor int de máscara de bits - extracto 1 bits valoradas

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

  •  05-10-2019
  •  | 
  •  

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?

¿Fue útil?

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

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top