7
votes

Nombre de bit non défini à gauche de la plupart des bits d'ensemble significatif?

En supposant que l'entier 64 bits 0x000000000000FFFF qui serait représenté comme xxx

Comment puis-je trouver la quantité de bits non défini à gauche du bit de jeu le plus significatif ( celui marqué avec>)?


5 commentaires

Êtes-vous intéressé par C, C # ou C ++? La théorie est la même chose, mais les langues sont différentes.


Depuis que j'ai supposé qu'il y a une magie bit-twiddling de faire cela et il semble à peu près la même chose dans toutes les langues que cela n'a pas vraiment d'importance.


Google "fxtobbook.pdf", chapitre 1.6.1


Il y a un certain nombre de raccourcis que vous pouvez prendre si cette valeur est toujours du modèle 0 * 1 * (tous les 0, suivi de tous les 1s), est-ce le cas?


@jkerian oui ... alors c'est juste 64 - BitCount (valeur). Recherchez PopCount ou Debruijn pour des moyens efficaces de compter les bits.


10 Réponses :


1
votes

Je ne suis pas sûr d'avoir compris le problème correctement. Je pense que vous avez une valeur de 64 bits et que vous souhaitez trouver le nombre de zéros de premier plan.

Un moyen serait de trouver le bit le plus significatif et de soustraire simplement sa position de 63 (en supposant que le bit le plus bas est le bit 0). Vous pouvez découvrir le bit le plus significatif en testant si un bit est défini à partir d'une boucle sur les 64 bits.

Une autre façon peut être d'utiliser le (non standard) __ intégré_clz dans GCC.


0 commentaires

1
votes

la même idée que User470379's , mais comptant ...
Supposons que tous les 64 bits sont non définis. Bien que la valeur soit supérieure à 0, continuez à déplacer la valeur droite et décrémentation du nombre de bits non définis: xxx


1 commentaires

Ne le faites pas de cette façon, s'il vous plaît. Ceci tandis que () boucle exécutera 64 fois. Vous pouvez le faire dans 6 itérations de boucle, puisque vous pouvez cloisons binaires le problème. Consultez ma réponse, basée sur la mise en œuvre de jeux de pirate de pirate.



2
votes

Si vous avez affaire à des entiers non signés, vous pouvez le faire:

#include <math.h>
int numunset(uint64_t number)
{
    int nbits = sizeof(uint64_t)*8;
    if(number == 0)
        return nbits;
    int first_set = floor(log2(number));
    return nbits - first_set - 1;
}


1 commentaires

Oh oui log2 est chère cher! J'ai même oublié cette possibilité. Je ne sais pas comment de telles choses sont implémentées dans le processeur FPU, mais le calcul de toute fonction non arithmétique conduit généralement à calculer une somme de la série. Je crois qu'une telle chose prend beaucoup de cycles de processeur.



0
votes

Essayez

int countBits(int value)
{
    int result = sizeof(value) * CHAR_BITS;  // should be 64

    while(value != 0)
    {
        --result;
        value = value >> 1; // Remove bottom bits until all 1 are gone.
    }
    return result;
}


0 commentaires

6
votes

en droite C (long longs sont 64 bits sur ma configuration), pris à partir de mises en œuvre similaires de Java: (Mis à jour après un peu plus de lecture sur le poids de Hamming)

Un peu plus d'explication: la partie supérieure vient de définir un peu à le droit du plus important 1, puis la nier ensuite. (c'est-à-dire que tous les 0 à la gauche de la "gauche" du plus important 1 sont maintenant 1 et tout le reste est 0). P>

alors j'ai utilisé un Hamming Poids Mise en œuvre Pour compter les bits. P>

unsigned long long i = 0x0000000000000000LLU;

i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i |= i >> 32;
// Highest bit in input and all lower bits are now set. Invert to set the bits to count.
i=~i;

i -= (i >> 1) & 0x5555555555555555LLU; // each 2 bits now contains a count
i = (i & 0x3333333333333333LLU) + ((i >> 2) & 0x3333333333333333LLU); // each 4 bits now contains a count
i = (i + (i >> 4)) & 0x0f0f0f0f0f0f0f0fLLU; // each 8 bits now contains a count 
i *= 0x0101010101010101LLU; // add each byte to all the bytes above it
i >>= 56; // the number of bits

printf("Leading 0's = %lld\n", i);


0 commentaires

1
votes

Je suis d'accord avec l'idée de recherche binaire. Cependant, deux points sont importants ici:

  1. La gamme de réponses valides à votre question est de 0 à 64 inclusive . En d'autres termes - il peut y avoir 65 des réponses différentes à la question. Je pense que tous ceux qui ont affiché la solution "Recherche binaire" ont manqué ce point, par conséquent, ils auront une réponse erronée pour zéro ou un numéro avec le MSB Bit On.
  2. Si la vitesse est critique - vous pouvez éviter la boucle. Il y a un moyen élégant d'atteindre cet utilisation de modèles.

    Le modèle de modèle suivant trouve le MSB correctement de toute variable de type non signé. xxx


0 commentaires

1
votes

Vous allez ici, assez trivial pour mettre à jour comme vous avez besoin pour les autres tailles ...

int bits_left(unsigned long long value)
{
  static unsigned long long mask = 0x8000000000000000;
  int c = 64;
  // doh
  if (value == 0)
    return c;

  // check byte by byte to see what has been set
  if (value & 0xFF00000000000000)
    c = 0;
  else if (value & 0x00FF000000000000)
    c = 8;
  else if (value & 0x0000FF0000000000)
    c = 16;
  else if (value & 0x000000FF00000000)
    c = 24;
  else if (value & 0x00000000FF000000)
    c = 32;
  else if (value & 0x0000000000FF0000)
    c = 40;
  else if (value & 0x000000000000FF00)
    c = 48;
  else if (value & 0x00000000000000FF)
    c = 56;

  // skip
  value <<= c;

  while(!(value & mask))
  {
    value <<= 1;
    c++;
  }

  return c;
}


0 commentaires

4
votes

Basé sur: http://www.hackersdelight.org/hdcode/nlz.c.ca .txt xxx pré>

Si vous souhaitez une version qui vous permet de conserver votre déjeuner, vous allez ici: p>

int clz(uint64_t v) {
    int n=64,c=64;
    while (n) {
        n>>=1;
        if (v>>n) c-=n,v>>=n;
    }
    return c-v;
}


0 commentaires

1
votes
// clear all bits except the lowest set bit
x &= -x;     

// if x==0, add 0, otherwise add x - 1. 
// This sets all bits below the one set above to 1.
x+= (-(x==0))&(x - 1);

return 64 - count_bits_set(x);
Where count_bits_set is the fastest version of counting bits you can find. See https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel for various bit counting techniques.

3 commentaires

Comme il se trouve, la première ligne ne coupe pas toutes les bits, à l'exception du le plus bas Ensignez-en?


@Jeppestignielsen, ah, donc ça fait! Je ne sais pas pourquoi je lui ai répondu de cette façon de rétrospectivement.


-1 Comment cela a-t-il été accepté? C'est complètement faux. Premièrement, il essaie de calculer le nombre de positions de bits au-dessus du jeu de bits le plus bas, ce qui n'est pas ce qui a été demandé. Deuxièmement, la condition de la deuxième ligne est à l'envers. L'effet souhaité des deux premières lignes peut être obtenu avec si (x) x ^ = x-1 ... mais tant qu'un test est fait, on pourrait aussi bien faire Si (! X) renvoie ... , puis 0 peut être mappé sur n'importe quoi. (Mieux encore, rendez cette fonction non définie pour 0 et laissez l'appelant traiter avec elle.)



0
votes

Utilisez la base de journal 2 pour vous obtenir le chiffre le plus significatif qui est 1.

function get_pos_msd(int n){
    return int(log2(n))
}

last_zero = 64 - get_pos_msd(n)


0 commentaires