Cantidad de dígitos de un número en Python

Más ejercicios resueltos

Si deseas revisar más ejercicios resueltos, haz click en el siguiente botón. 

A continuación presentamos 3 alternativas de solución al problema de contar la cantidad de dígitos de un número en Python. Si deseas ver el enunciado del problema, haz click en el siguiente enlace

A continuación presentamos 3 alternativas de solución usando tanto la estructura algorítmica iterativa, la recursión, así como los logaritmos

Función principal

La función principal tendrá como objetivo la lectura de datos e invocación a la función \texttt{cuenta\_digitos}. No existe ninguna validación que realizar al número n, esto debido a que el enunciado del problema indica que el dominio del número corresponde al conjunto de los números enteros. La lectura en Python la realizaremos a través de la función \texttt{input} y el valor leído se almacenará en la variable \texttt{numero}. Usamos la función \texttt{int} para transformar en texto leído a una variable entera.

Debido a que las distintas alternativas de solución que se analizarán, esperan que el número que se pase como parámetro sea un número natural, se actualiza numero leído con su valor absoluto. ¿Por qué esto es necesario? Esto en realidad corresponde con el detalle de la implementación de cada alternativa de solución. Lo veremos más adelante en cada solución, pero lo que podemos ir adelantando es que todas ellas solo funcionarán para los números naturales (numero>0). Para obtener el valor absoluto de un número usamos la función \texttt{abs} que Python incorpora de manera nativa.

numero=int(input("Ingrese un número: "))
numero=abs(numero)
print("El número tiene {:d} dígito(s)".format(cuenta_digitos(numero))) 

Cuenta dígitos

Procederemos ahora a implementar la función \texttt{cuenta\_digitos}. Esta función recibe como parámetro un número natural \texttt{numero} mayor o igual a cero. Retorna la cantidad de dígitos del número pasado como parámetro.

Procederemos a presentar detalladamente la implementación del método \texttt{cuenta\_digitos} usando en primer lugar la estructura algorítmica iterativa con entrada controlada. Detallaremos tres puntos en particular:

  • El control de flujo.
  • El conteo de los dígitos.
  • El tratamiento del número cero.

Control de flujo

Como en todo problema iterativo, el primer punto a gestionar es el control de flujo. La versión que implementaremos se basa en la iteración y se busca que en cada iteración se cuenta un dígito del número que está siendo analizado. Entonces, ¿cómo realizamos el control de flujo? 

  1. Variable de control. El control de gestionaremos a través del mismo parámetro \texttt{numero}. Usaremos a \texttt{numero} como nuestra variable de control de la iteración.
  2. Condición de la iteración. Dado que queremos ir extrayendo un dígito en cada iteración, seguiremos iterando mientras existan dígitos para sacar. En otras palabras, mientras \texttt{numero>0}. Cuando \texttt{numero} contenga el valor de cero, asumiremos que no existirán más dígitos por extraer y la iteración deberá de terminar.
  3. Actualización de la variable de control. Al final de cada iteración debemos actualizar \texttt{numero}. Debemos quitarle un dígito a la variable de control \texttt{numero}. Esto se logra simplemente dividiendo entre 10 al número en cuestión. Utilizamos para este fin la operación de asignación \texttt{//=}. Recuerde que \texttt{numero//=10} equivale a \texttt{numero=numero//10}.
def cuenta_digitos(numero):
    while numero>0:
 
        numero//=10 

Conteo de dígitos

El siguiente paso es definir una variable en donde se llevará la cuenta de los dígitos que se van a ir extrayendo. Esta variable, comúnmente llamada contador, la hemos identificado con \texttt{total\_digitos}. Básicamente lo que hacemos es incrementar su valor en uno en cada iteración. Contando los dígitos que vamos obteniendo del número. Para incrementar el contador hemos utilizado el operador de asignación \texttt{+=}. Recuerde que \texttt{total\_digitos+=1} equivale a \texttt{total\_digitos=total\_digitos+1}.

def cuenta_digitos(numero):
    total_digitos = 0
    while numero>0:
        total_digitos+=1
        numero//=10 

Caso particular del número 0

Hay un caso particular que debemos manejar en nuestro programa. Se da cuando el parámetro \texttt{numero} es igual a cero. Dado que en la versión iterativa implementada, usamos como condición de iteración \texttt{numero>0}, nunca se ejecutará cuando \texttt{numero=0}, por lo que la variable \texttt{total\_digitos} contendrá el valor de \texttt{0}. Entonces, en esta situación, asignamos el valor de \texttt{1} a la variable \texttt{total\_digitos}. Para esto usamos un estructura selectiva simple inmediatamente después del ciclo iterativo.

def cuenta_digitos(numero):
    total_digitos = 0
    while numero>0:
        total_digitos+=1
        numero//=10
    if total_digitos==0:
        total_digitos+=1
    return total_digitos 

Cuenta dígitos: versión recursiva

Función recursiva

La siguiente versión que implementaremos será la versión recursiva. El caso base será cuando \texttt{numero==0}. En esta situación se retorna el valor de \texttt{0}. En el caso recursivo se retorna \texttt{1} + la llamada recursiva pero actualizando el parámetro \texttt{numero}. El parámetro \texttt{n} lo dividimos entre 10 antes de hacer la invocación.  Usamos para este fin, la división entera.

def cuenta_digitos(numero):
    if numero == 0:
        return 0
    return 1 + cuenta_digitos(numero // 10) 

Función principal

La versión recursiva que hemos implementado posee un problema. No controla el caso cuando el \texttt{numero} pasado como parámetro es cero. En este situación hemos optado por hacer dicho control en la función principal. De esta forma si el número leído  es \texttt{0}, se imprime el valor de \texttt{1}. En caso contrario se imprime el valor que retorna la función recursiva. 

Hemos usado el operador ternario \texttt{if else} para realizar la condicional. El operador ternario posee 3 operandos. Si el segundo operando se evalúa como verdadero, se retorna el primer operando, en caso contrario se retorna el tercer operando. La ventaja que ofrece es que permite escribir condicionales de una forma muy simple en una línea. En el programa implementado, hemos la expresión condicional de la siguiente manera \texttt{1 if numero==0 else cuenta\_digitos(numero)}.

Otra opción que hubiésemos podido tomar en cuenta es encapsular esta verificación del cero en otra función. Haciendo transparente este detalle de implementación.

import math

def cuenta_digitos(numero):
    if numero == 0:
        return 1
    return int(math.log10(numero) + 1) 

Cuenta dígitos: versión usando logaritmos

Otra versión muy usada para contar la cantidad de dígitos de un número es la que utiliza logaritmos. Esta versión es muy simple de implementar pero antes de ello se debe entender qué se entiende por logaritmo.

Sea b un número real positivo no nulo distinto de 1, y x otro número positivo no nulo. Se denomina logaritmo del número x en la base b, al exponente l al que debe elevarse la base b para obtener dicho número x. El logaritmo se expresa de la siguiente manera \log_bx y si \log_bx =l \leftrightarrow b^l=x . Por ejemplo \log_{5}{625}=4 ya que 625=5^4=5 \times 5 \times 5 \times 5. El logaritmo es la operación inversa a la exponenciación.

Pues bien, ¿qué tienen que ver los logaritmos con la cantidad de dígitos de un número? Pues mucho. Veamos. Supongamos que tenemos el número 123. Si le aplicamos el logaritmo en base 10, obtenemos que \log_{10}{123} \approx 2.089905111 . Esto significa que 10^{2.089905111}=123. Probemos ahora con otro número, por ejemplo 654, \log_{10}{654} \approx 2.815577748 . Esto significa que 10^{2.815577748}=654. Ahora con 1000, \log_{10}{1000} = 3 . Esto significa que 10^{3}=1000.

Lo que el logaritmo en base 10 no está retornando es a cuanto debemos elevar 10 para que retorne el número en cuestión. Cómo sabemos que estamos usando el sistema de numeración decimal, es decir, en base 10.  Básicamente lo que el logaritmo no está respondiendo es cuántas potencias de 10 yo debo multiplicar para llegar a dicho número. Pero cada vez que usamos una potencia de 10, significa que el dígito posee un dígito adicional a dicha potencia. Por ejemplo, si yo puedo representar un número con 3 potencias de 10, significará que tendrá 4 dígitos, pues 10^3=1000. Si yo puedo representar un número con  2.089905111 potencias de 10, entonces se requerirán 3 dígitos. Y es esta la razón por la cual podemos obtener la cantidad de dígitos dado el logaritmo.

import math

def cuenta_digitos(numero):
    if numero == 0:
        return 1
    return int(math.log10(numero) + 1) 

Bonus track: cuenta dígitos en otra base

El logaritmo también se puede usar para contar la cantidad de dígitos que posee el número en otras bases. Simplemente en lugar de usar como base del logaritmo 10, usamos la base en la cual deseamos obtener la cantidad de dígitos. 

import math

def cuenta_digitos(numero, base):
    if numero == 0:
        return 1
    return int(math.log(numero)/math.log(base)) + 1 

Conclusión

Hemos presentado en este artículo, 3 propuestas de solución al problema de contar dígitos de un número en Python. Se ha utilizado para el diseño algorítmico la técnica del diseño descendente y se ha controlado  el flujo en los módulos usando estructuras selectivas e iterativas. Podrá descargar la solución propuesta en el repositorio GitHub de iterando++ a través del siguiente enlace

Hemos preparado otros artículos adicionales en donde describimos al detalle la implementación de este problema en PSeInt y otros lenguajes de programación. Te invitamos a leer los siguientes artículos de iterando++

Si te interesa profundizar más en el desarrollo en Python, los dos mejores libros que se han escrito son Learning Python de Mark Lutz y Python Crash Course de Eric Matthes.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *