web-dev-qa-db-fra.com

Longueur en bits d'un entier positif en Python

1 = 0b1 -> 1
5 = 0b101 -> 3
10 = 0b1010 -> 4
100 = 0b1100100 -> 7
1000 = 0b1111101000 -> 10
…

Comment obtenir la longueur en bits d’un entier, c’est-à-dire le nombre de bits nécessaires pour représenter un entier positif en Python?

34
user288832

Dans python 2.7+, il existe une méthode int.bit_length() :

>>> a = 100
>>> a.bit_length()
7
157
SilentGhost
>>> len(bin(1000))-2
10
>>> len(bin(100))-2
7
>>> len(bin(10))-2
4

Note : ne fonctionnera pas pour les nombres négatifs, il faudra peut-être soustraire 3 au lieu de 2

20
YOU

Si votre version Python en est dotée (≥2.7 pour Python 2, ≥3.1 pour Python 3), utilisez la méthode bit_length de la bibliothèque standard.

Sinon, len(bin(n))-2comme suggéré par VOUS est rapide (car il est implémenté en Python). Notez que cela renvoie 1 pour 0.

Sinon, une méthode simple consiste à diviser à plusieurs reprises par 2 (ce qui est un simple décalage de bit) et à compter le temps nécessaire pour atteindre 0.

def bit_length(n): # return the bit size of a non-negative integer
    bits = 0
    while n >> bits: bits += 1
    return bits

Il est nettement plus rapide (du moins pour les grands nombres - un repère rapide en dit plus de 10 fois plus rapide pour 1000 chiffres) de passer d’un mot à l’autre, puis de revenir en arrière et de travailler sur les bits du dernier mot.

def bit_length(n): # return the bit size of a non-negative integer
    if n == 0: return 0
    bits = -32
    m = 0
    while n:
        m = n
        n >>= 32; bits += 32
    while m: m >>= 1; bits += 1
    return bits

Dans ma référence rapide, len(bin(n)) est sorti nettement plus rapidement que même la version de bloc de la taille d'un mot. Bien que bin(n) construise une chaîne qui est immédiatement supprimée, elle est la meilleure en raison de la présence d'une boucle interne compilée en code machine. (math.log est encore plus rapide, mais ce n'est pas important car c'est faux.)

1
Gilles

Voici un autre moyen:

def number_of_bits(n):
    return len('{:b}'.format(n))

Pas si efficace, je suppose, mais cela ne figure dans aucune des réponses précédentes ...

0
goodvibration