Question

Je calcul de l'équivalent int d'un ensemble donné de bits et de stockage que dans la mémoire. A partir de là, je voudrais déterminer les 1 bits de valeur du bitmask d'origine. Exemple:

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

Des idées pour une implémentation en Java?

Était-ce utile?

La solution

Sur BitSet

java.util.BitSet pour stocker, de plus, un ensemble de bits.

Voici comment vous pouvez convertir un int à un BitSet, basé sur les bits dans le int est défini:

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

Alors maintenant, vous pouvez faire ce qui suit:

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

Et pour être complet, voici la transformation inverse:

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

composant Alors les deux ensemble, nous obtenons toujours revenir le numéro d'origine:

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

Sur l'indexation basé sur 0

Notez que cette utilisation d'indexation basé sur 0, ce qui est l'indexation plus communément utilisé pour les bits (et plus tout le reste en Java). Ceci est également plus correct. Dans ce qui suit, ^ désigne exponentiation:

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 vous insistez sur l'utilisation de l'indexation de base 1, cependant, vous pouvez utiliser bs.set(k+1); et (1 << (k-1)) dans les extraits ci-dessus. Je vous conseille vivement contre cette recommandation, cependant.

Questions connexes

Autres conseils

Pour peu tripoter, java.lang.Integer a quelques méthodes statiques très utiles. Essayez ce code comme base de départ pour votre problème:

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

Je peux vous montrer la mise en œuvre C #, Java devrait être très similaire.

int value = 33;
int index = 1;

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

   index++;
   value /= 2;
}

Si vous voulez obtenir un tableau comme ça, vous aurez probablement besoin de boucler le nombre de bits que vous voulez vérifier & l'entier avec un peu décalé 1 pour chaque étape.

Quelque chose comme (pseudo):

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

serait quelque chose comme une variation crissement bits:

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

Notez que puisque les bits sont indexés de 1 comme vous avez demandé, bits[0] reste inutilisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top