Memorizzazione valore intero della maschera di bit - estratto di 1 bit di valore

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

  •  05-10-2019
  •  | 
  •  

Domanda

Sono calcolando int equivalente di un dato insieme di bit e memorizzazione che nella memoria. Da lì, desidero determinare tutti 1 bit di valore dalla maschera di bit originale. Esempio:

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

Idee per un'implementazione in Java?

È stato utile?

Soluzione

On BitSet

java.util.BitSet per memorizzare, bene, un insieme di bit.

Ecco come è possibile convertire da un int ad un BitSet, in base alla quale i bit nel int è impostato:

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;
}

Così ora è possibile effettuare le seguenti operazioni:

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

E solo per completezza, ecco la trasformazione inversa:

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

Quindi, la composizione e due insieme, abbiamo sempre tornare il numero originale:

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

On 0 a base di indicizzazione

Si noti che questo uso di indicizzazione 0-based, che è l'indicizzazione più comunemente usato per bit (e la maggior parte tutto il resto in Java). Questo è anche più corretto. Nel seguito, ^ denota l'elevamento a potenza:

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

Se ti ostini a usare l'indicizzazione 1-based, tuttavia, è possibile utilizzare bs.set(k+1); e (1 << (k-1)) nei frammenti di cui sopra. Vorrei consigliare vivamente contro questa raccomandazione, però.

Domande correlate

Altri suggerimenti

Per po giocherellare, java.lang.Integer ha alcuni metodi statici molto utili. Prova questo codice come base di partenza per il vostro 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;
}

posso mostrarvi C # implementazione, Java dovrebbe essere molto simile.

int value = 33;
int index = 1;

while (value > 0)
{
   if ((value % 2) == 1)
      Console.WriteLine(index);

   index++;
   value /= 2;
}

Se si vuole ottenere un array del genere è probabile che tu bisogno di ciclo il numero di bit che si desidera controllare & il numero intero con un po 'spostato 1 per ogni passaggio.

Qualcosa di simile (pseudo):

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

Una variazione po-scricchiolio sarebbe qualcosa di simile:

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;
}

Si noti che dal momento che i bit sono indicizzati da 1 come da voi richiesto, bits[0] rimane inutilizzato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top