Memorizzazione valore intero della maschera di bit - estratto di 1 bit di valore
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?
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
- Che cosa l'operatore
^
fare in Java ? - - in realtà non è l'elevamento a potenza
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.