OVH Cloud OVH Cloud

comptage de bits

15 réponses
Avatar
zombie
Bonjour,

Question d'algorithmique basique. Quelle est la fonction la plus
efficace que vous connaissez en C pour compter le nombres de bits =E0 1
dans un "unsigned int" (entier non sign=E9 cod=E9 sur 4 octets, en
g=E9n=E9ral) ?

Exemple pour 1, 2, 4, 8, 16... retour 1
pour 3, 5, 9, 17... retour 2
pour 15 (1111) retour 4
etc...

unsigned int countBits (unsigned int iValue)
{
...
}

5 réponses

1 2
Avatar
Erwan David
Vincent Lefevre <vincent+ écrivait :


J'ai oublié de dire que les entiers en question étaient des int
(en général, quand on parle d'entiers sans préciser, ce sont des
entiers signés).



donc la réponse est "ça dépend". le nombre de bits à 1 ne sera pas
forcément le même dans toutes les représentations des entiers signés.

(-1 sur 32 bits, 32 bits à 1 en complément à 2,
2 bits à 1 en signe+mantisse).

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Avatar
Antoine Leca
En news:,
zombie va escriure:
Par exemple, dans le minimum de deux entiers:
r = y + ((x - y) & -(x < y)); // min(x, y)
x - y peut provoquer un overflow, d'où comportement indéfini.





Sans compter le cas où les entiers sont en signe+magnitude... :-)

Ce code est surtout intéressant parce qu'en assembleur i386,
l'opération -(x < y) se résume à l'instruction
SETL E?X
et donc la formule donne un code extrêmement compact.
Comme dit l'auteur, cette formule « peut » être avantageuse sur l'évidente
utilisation de l'opérateur ?:, ce que l'on peut aussi comprendre comme quoi
elle ne l'est pas toujours...


Mais l'overflow n'existe que pour les flottants, non ?



Non. En C, le débordement _peut_ exister pour les flottants, et _peut_
exister pour les opérations entières signées.
Ni l'une ni l'autre des deux options sont obligatoires, et elles n'ont pas à
être systématiques (peut le faire une fois sur deux, par exemple ; ou selon
les types mis en ½uvre).

Si x et y sont des unsigned int, le calcul se fait modulo 2^32,



... modulo UINT_MAX+1 pour être précis.


Antoine
Avatar
Sleipnir
ben le plus simple que je vois c'est :

un test "le nombre est impair? si oui, +1 sinon alors rien"
décalage de bit vers la droite
etc et tant que le nombre n'est pas egal à 0...

Qui dit mieux ?


"zombie" a écrit dans le message de
news:
Bonjour,

Question d'algorithmique basique. Quelle est la fonction la plus
efficace que vous connaissez en C pour compter le nombres de bits à 1
dans un "unsigned int" (entier non signé codé sur 4 octets, en
général) ?

Exemple pour 1, 2, 4, 8, 16... retour 1
pour 3, 5, 9, 17... retour 2
pour 15 (1111) retour 4
etc...

unsigned int countBits (unsigned int iValue)
{
...
}
Avatar
Jean-marc
Sleipnir wrote:
ben le plus simple que je vois c'est :

un test "le nombre est impair? si oui, +1 sinon alors rien"
décalage de bit vers la droite
etc et tant que le nombre n'est pas egal à 0...



C'est la méthode classique par itération:

int bitcount (unsigned int n)
{
int count=0;
while (n)
{
count += n & 0x1u ;
n >>= 1 ;
}
return count ;
}

Qui dit mieux ?



Des tas d'autres algorithmes décrits sur la page indiquée plus haut
dans ce thread:
http://infolab.stanford.edu/~manku/bitcount/bitcount.html

La méthode que tu proposes fonctionne bien mais à un temps de calcul
proportionnel au nombre de bits du nombre, alors que d'autres ont un
temps de calcul proportionnel au nombre de 0 ou de 1, voire
(beaucoup) moins pour les méthodes précalculées. On peut faire
de 1 à 20 fois plus rapide en fonction des options de compil.

--
(jean_marc_n2)
Avatar
Sleipnir
bon ben... je prends lol =)


et oui, o(n)... c'est carrément pas le top lol



"Jean-marc" a écrit dans le message de
news:48877595$0$2859$
Sleipnir wrote:
ben le plus simple que je vois c'est :

un test "le nombre est impair? si oui, +1 sinon alors rien"
décalage de bit vers la droite
etc et tant que le nombre n'est pas egal à 0...



C'est la méthode classique par itération:

int bitcount (unsigned int n)
{
int count=0;
while (n)
{
count += n & 0x1u ;
n >>= 1 ;
}
return count ;
}

Qui dit mieux ?



Des tas d'autres algorithmes décrits sur la page indiquée plus haut
dans ce thread:
http://infolab.stanford.edu/~manku/bitcount/bitcount.html

La méthode que tu proposes fonctionne bien mais à un temps de calcul
proportionnel au nombre de bits du nombre, alors que d'autres ont un
temps de calcul proportionnel au nombre de 0 ou de 1, voire
(beaucoup) moins pour les méthodes précalculées. On peut faire
de 1 à 20 fois plus rapide en fonction des options de compil.

--
(jean_marc_n2)







1 2