346 votes

Comment trouver la longueur des chiffres dans un entier?

En Python, comment trouvez-vous le nombre de chiffres dans un entier ?

3 votes

Je ne comprends pas votre question. Vouliez-vous dire la taille d'un entier? Voulez-vous trouver le nombre de chiffres? Veuillez clarifier.

453voto

GeekTantra Points 2606

Si vous voulez la longueur d'un entier comme le nombre de chiffres dans l'entier, vous pouvez toujours le convertir en chaîne de caractères comme str(133) et trouver sa longueur comme len(str(123)).

31 votes

Bien sûr, si vous cherchez le nombre de chiffres, cela produira un résultat trop grand pour les nombres négatifs, car il comptera le signe négatif.

74 votes

Salut, c'est une solution lente. J'ai calculé le factoriel d'un nombre aléatoire à 6 chiffres et j'ai trouvé sa longueur. Cette méthode a pris 95.891 secondes. Et la méthode Math.log10 n'a pris que seulement 7.486343383789062e-05 secondes, environ 1501388 fois plus rapide !

6 votes

Cela n'est pas seulement lent, mais consomme beaucoup plus de mémoire et peut causer des problèmes en grand nombre. utilisez Math.log10 à la place.

354voto

gnibbler Points 103484

Sans conversion en chaîne de caractères

import math
digits = int(math.log10(n))+1

Pour gérer également les zéros et les nombres négatifs

import math
if n > 0:
    digits = int(math.log10(n))+1
elif n == 0:
    digits = 1
else:
    digits = int(math.log10(-n))+2 # +1 si vous ne comptez pas le '-'

Vous voudriez probablement mettre cela dans une fonction :)

Voici quelques benchmarks. La len(str()) est déjà en retard pour des nombres même assez petits

timeit math.log10(2**8)
1000000 boucles, meilleure de 3: 746 ns par boucle
timeit len(str(2**8))
1000000 boucles, meilleure de 3: 1.1 µs par boucle

timeit math.log10(2**100)
1000000 boucles, meilleure de 3: 775 ns par boucle
timeit len(str(2**100))
100000 boucles, meilleure de 3: 3.2 µs par boucle

timeit math.log10(2**10000)
1000000 boucles, meilleure de 3: 844 ns par boucle
timeit len(str(2**10000))
100 boucles, meilleure de 3: 10.3 ms par boucle

1 votes

Peut-être chiffres = n et 1 + int(math.log(abs(n), 10))

10 votes

En utilisant log10 pour cela est une solution mathématique ; utiliser len(str()) est une solution de programmeur, et est plus clair et plus simple.

90 votes

@Glenn: J'espère vraiment que vous n'impliquez pas que c'est une mauvaise solution. La solution naïve en O(log10 n) du programmeur fonctionne bien dans un code ad hoc et de prototypage - mais je préférerais voir une solution élégante en O(1) des mathématiciens dans le code de production ou une API publique. +1 pour gnibbler.

27voto

Alex Martelli Points 330805

En Python, les ints 2.* prennent soit 4, soit 8 octets (32 ou 64 bits), en fonction de votre installation Python. sys.maxint (2**31-1 pour les ints 32 bits, 2**63-1 pour les ints 64 bits) vous indiquera quelle des deux possibilités est en vigueur.

En Python 3, les ints (comme les longs en Python 2) peuvent avoir des tailles arbitraires jusqu'à la quantité de mémoire disponible; sys.getsizeof vous donne une bonne indication pour n'importe quelle valeur donnée, bien qu'il compte également un certain surcoût fixe:

>>> import sys
>>> sys.getsizeof(0)
12
>>> sys.getsizeof(2**99)
28

Si, comme le suggèrent d'autres réponses, vous pensez à une certaine représentation en chaîne de la valeur entière, alors prenez simplement la len de cette représentation, que ce soit en base 10 ou autrement!

1 votes

Désolé, cette réponse a été rejetée. Elle est informative et aborde de manière plausible le point de la question (si seulement elle était plus spécifique sur le 'len' souhaité). +1

3 votes

Cela semble intéressant mais je ne suis pas sûr comment extraire la longueur.

16voto

BiGYaN Points 1818

Laissez le nombre être n alors le nombre de chiffres dans n est donné par :

math.floor(math.log10(n))+1

Notez que cela donnera des réponses correctes pour les entiers positifs < 10e15. Au-delà, les limites de précision du type de retour de math.log10 entrent en jeu et la réponse peut être décalée de 1. Je suis simplement len(str(n)) au-delà de cela ; cela nécessite un temps O(log(n)) qui est le même que celui d'itération sur les puissances de 10.

Merci à @SetiVolkylany d'avoir attiré mon attention sur cette limitation. Il est étonnant de voir comment des solutions en apparence correctes ont des avertissements dans les détails de mise en œuvre.

1 votes

Il ne fonctionne pas si n est en dehors de la plage [-999999999999997, 999999999999997]

0 votes

@SetiVolkylany, je l'ai testé jusqu'à 50 chiffres pour python2.7 et 3.5. Il suffit de faire un assert list(range(1,51)) == [math.floor(math.log10(n))+1 for n in (10**e for e in range(50))].

2 votes

Essayez-le avec Python2.7 ou Python3.5 >>> math.floor(math.log10(999999999999997))+1 15.0 >>> math.floor(math.log10(999999999999998))+1 16.0. Regardez ma réponse stackoverflow.com/a/42736085/6003870.

3voto

de math import log10
chiffres = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X