7
votes

Trouver des tractions 0S dans un numéro binaire

Comment trouver le nombre de tractions 0S dans un numéro binaire? Basé sur K & R BitCount Exemple de recherche des 1S dans un numéro binaire, je l'ai modifié un peu pour trouver le traction 0S.

int bitcount(unsigned x)
{
  int b;
  for(b=0;x!=0;x>>=1)
      {
        if(x&01)
          break;
        else
          b++;
      }


1 commentaires

Est-ce que cela répond à votre question? Nombre de zéros traînants


7 Réponses :


0
votes

devrait être: xxx

ou même xxx

ou même (yay!) xxx

ou ...

ah, peu importe, Il y a 100500 millions de méthodes de faire ce . Utilisez ce que vous avez besoin ou comme.


4 commentaires

Lien fourni juste pour une référence, et c'est pour compter un bit. Mais tu as eu l'idée.


Quelle est l'utilisation de x >> 1 dans ces codes quand ils ne sauvent pas?


Eh bien, il est étrange d'entendre cette question de quelqu'un qui tente de mettre en œuvre une telle tâche. C'est ce qu'on appelle un bit shift: cs.umd.edu/ Classe / Sum2003 / CMSC311 / Notes / Bitop / BitShift.HTML


"Shifting ne change pas de valeurs", a déclaré dans votre lien mentionné. x >> 1; sans enregistrer le résultat dans une variable. C'est comme écrire i + 1; !!!



0
votes

Je pense que votre méthode fonctionne (bien que vous souhaiteriez utiliser non signé INT ). Vous vérifiez le dernier chiffre à chaque fois, et s'il est zéro, vous le rejette un incrément du nombre de bits zéro traînant.

Je pense que pour les zéros traînants, vous n'avez pas besoin d'une boucle.

Considérez les éléments suivants:

  • Que se passe-t-il avec le nombre (dans la représentation binaire, bien sûr) si vous soustrayez 1? Quels chiffres changent, qui restent le même?
  • Comment pouvez-vous combiner le numéro d'origine et la version décrémentée telle que seules les bits représentant des zéros traînants sont laissées?

    Si vous appliquez correctement les étapes ci-dessus, vous pouvez simplement trouver le bit le plus élevé dans les étapes O (LG N) (look ici si vous êtes intéressé à faire).


0 commentaires

7
votes

sur GCC sur la plate-forme X86, vous pouvez utiliser __ intégré_ctz (NO) Sur les compilateurs Microsoft pour x86, vous pouvez utiliser _bitscanforward

Ils émettent tous deux une instruction BSF


0 commentaires

12
votes

Voici un moyen de calculer le comptage en parallèle pour une meilleure efficacité:

unsigned int v;      // 32-bit word input to count zero bits on right
unsigned int c = 32; // c will be the number of zero bits on the right
v &= -signed(v);
if (v) c--;
if (v & 0x0000FFFF) c -= 16;
if (v & 0x00FF00FF) c -= 8;
if (v & 0x0F0F0F0F) c -= 4;
if (v & 0x33333333) c -= 2;
if (v & 0x55555555) c -= 1;


2 commentaires

Comment ça marche? Il est difficile de comprendre comment cela a été dérivé.


C'est une recherche de bisection / binaire sur le niveau de bit.



3
votes

Une autre approche (je suis surprise que cela ne soit pas mentionné ici) serait de construire une table de 256 entiers, où chaque élément de la matrice est le 1 bit le plus bas pour cet indice. Puis, pour chaque octet dans l'entier, vous regardez dans la table.

Quelque chose comme ça (je n'ai pas pris de temps pour le modifier, il s'agit simplement d'illustrer grossièrement l'idée): P>

int bitcount(unsigned x)
{
   static const unsigned char table[256] = { /* TODO: populate with constants */ };

   for (int i=0; i<sizeof(x); ++i, x >>= 8)
   {
      unsigned char r = table[x & 0xff];

      if (r)
         return r + i*8;    // Found a 1...
   }

   // All zeroes...
   return sizeof(x)*8;
}


0 commentaires

0
votes

Nous pouvons facilement l'obtenir en utilisant des opérations de bits, nous n'avons pas besoin de passer par tous les bits. Pseudo code: xxx


1 commentaires

Quel est le i ?



0
votes
-x = !(x) + 1 = !(a1b) + 1 = (!a)0(!b) + 1 = (!a)0(1...1) + 1 = (!a)1(0...0) = (!a)1b 

0 commentaires