¿Cómo puedo contar los dígitos de un entero sin una conversión de cuerdas?

StackOverflow https://stackoverflow.com/questions/554521

  •  23-08-2019
  •  | 
  •  

Pregunta

Me temo que no hay una respuesta simple y obvia a esta pregunta. Necesito para determinar cuántos dígitos amplia un número de elementos es, por lo que puede rellenar cada número de artículo con el mínimo número de ceros necesarios para mantener la alineación. Por ejemplo, quiero que no hay ceros a la izquierda si el total es <10, 1 si es entre 10 y 99, etc.

Una solución sería a emitir el elemento recuento en una cadena y luego contar caracteres. Puaj! ¿Hay una mejor manera?

Edit: Yo no habría pensado utilizar el logaritmo común (yo no lo sabía tal cosa existiera). Por lo tanto, no es obvio - para mí -. Pero definitivamente sencilla

¿Fue útil?

Solución

Esto debe hacerlo:

int length = (number ==0) ? 1 : (int)Math.log10(number) + 1;

Otros consejos

int length = (int)Math.Log10(Math.Abs(number)) + 1;

Es posible que necesite para tener en cuenta el signo negativo ..

Una solución más eficiente que la división repetida se repetiría si las declaraciones con multiplica ... por ejemplo, (Donde n es el número cuyo número de dígitos que se requiere)

unsigned int test = 1;
unsigned int digits = 0;
while (n >= test)
{
  ++digits;
  test *= 10;
}

Si hay algún razonable límite superior en el número de elementos (por ejemplo, la gama de 32 bits de un unsigned int) a continuación, de una manera aún mejor es comparar con los miembros de algunos matriz estática, por ejemplo.

// this covers the whole range of 32-bit unsigned values
const unsigned int test[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };

unsigned int digits = 10;
while(n < test[digits]) --digits;

Si va a rellenar el número en .Net, entonces

num.ToString().PadLeft(10, '0') 

podría hacer lo que quiera.

Puede utilizar un bucle while, que probablemente será más rápido que un logaritmo ya que este utiliza la aritmética de enteros solamente:

int len = 0;
while (n > 0) {
    len++;
    n /= 10;
}

Lo dejo como ejercicio para el lector para ajustar este algoritmo para manejar cero y los números negativos.

Me hubiera publicado un comentario, pero mi puntuación representante no me va a conceder esa distinción.

Todo lo que quería señalar era que a pesar de que el registro (10) es un muy elegante (léase: muy pocos líneas de código) solución, es probablemente la más exigente en el procesador

.

Creo que la respuesta de jherico es probablemente la solución más eficiente y por lo tanto debe ser recompensado como tal.

Especialmente si usted va a estar haciendo esto por un montón de números ..

Dado que un número no tiene ceros a la izquierda, que está convirtiendo todos modos para agregarlos. No estoy seguro de por qué está tratando muy duro para evitarlo para encontrar la longitud cuando el resultado final tendrá que ser una cadena de todos modos.

Una solución es proporcionado por logaritmo en base 10, un poco exageración.

Puede recorrer y eliminar en un 10, contar el número de veces que bucle;

int num = 423;
int minimum = 1;
while (num > 10) {
    num = num/10;
    minimum++;
}

Está bien, no me puedo resistir: el uso /=:

#include <stdio.h>

int
main(){
        int num = 423;
        int count = 1;
        while( num /= 10)
                count ++;
        printf("Count: %d\n", count);
        return 0;
}
534 $ gcc count.c && ./a.out
Count: 3
535 $ 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top