Quantos algarismos formam o número n: uma abordagem prática
Essa pergunta parece simples, mas ela aparece o tempo todo em codeforces, interviews e em código legítimo de sistemas que precisam formatar IDs, hash ou números de controle. O problema é que a resposta correta muda dependendo do que você considera como entrada.
quantos algarismo formam o número n
No sentido mais direto, a pergunta pede uma função ou fórmula que, dada uma entrada numérica, retorne a quantidade de dígitos decimais dela. A resposta que todo mundo aprende na escola é floor(log10(n)) + 1 para n positivo. Funciona. Mas só funciona sob condições que as pessoas raramente verificam. Vou começar pelo que dá problema na prática. A primeira pegadinha que eu vi acontecer em produção foi com números que têm exatamente a potência de dez. floor(log10(1000)) + 1 deveria dar 4, porque 1000 tem quatro dígitos. Em várias bibliotecas, o logaritmo retorna algo como 2,9999999999999996 por causa de arredondamento de ponto flutuante, o que faz o floor retornar 2 em vez de 3. Aí a conta fecha errada e o resultado vira 3 quando deveria ser 4. Já vi isso quebrar um gerador de códigos de barras e um validador de CPF que usava contagem de dígitos como primeiro passo.
A correção que eu uso hoje é evitar log quando posso. Se a entrada é um inteiro sem sinal, a solução mais estável é simplesmente comparar potências de dez em uma sequência: se n < 10, tem 1 dígito; se n < 100, tem 2; se n
1000, tem 3; e assim por diante. Para inteiros de 64 bits, são no máximo 19 iterações, mas na realidade você raramente passa de 10 comparações. Isso elimina erro de ponto flutuante de uma vez e ainda é mais rápido do que chamar log em muitos casos. Se você não está no mundo dos inteiros exatos e a entrada chega como ponto flutuante, a coisa fica mais suja. float e double têm precisão finita, então números grandes demais já perdem dígitos antes mesmo de você medir quantos têm. Nesse cenário, usar conversão para string pode parecer a solução óbvia, mas ela introduz outro problema: a formatação científica. Quando um número fica muito grande ou muito pequeno, a representação em string muda para notação científica, como 1.23e+07, e contar caracteres nessa forma te dá um número totalmente errado.
Um caso específico que eu encontrei foi num sistema de lote financeiro onde os valores vinham como double e precisávamos contar dígitos para gerar uma chave de agrupamento. O número 9999999999999999 tem dezesseis dígitos, mas em double ele é arredondado para algo próximo de 10000000000000000. Se você aplicar log, acaba contando quinze dígitos e a chave sai errada. A solução foi rodar um round antes de contar, usando a unidade relevante, e depois usar a comparação em potências de dez em vez de qualquer cálculo logarítmico. Outra questão que poucos mencionam é como lidar com zero. A fórmula floor(log10(n)) + 1 não se aplica a n = 0, porque log10(0) é indefinido. Em qualquer implementação séria, zero tem um tratamento à parte e retorna 1. Se você esquecer disso, o código entra em falha silenciosa ou em exceção, dependendo da linguagem.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Números negativos também merecem atenção. Ao contar algarismos de um número como -347, o objetivo geral é contar apenas os dígitos significativos, ou seja, três. O sinal não entra na contagem. Isso significa que antes de qualquer lógica, você deve tomar o valor absoluto. Em linguagens como C e C++, tenha cuidado com INT_MIN, porque o absoluto dele pode transbordar se o tipo for assinado. Nesses casos, converter para o equivalente sem sinal antes de processar evita problema de overflow. Se a entrada vier como string, aí o jogo muda completamente. A contagem passa a ser um problema de parsing, não de matemática. Você precisa decidir se espaços, sinais e pontos decimais contam. No Brasil, onde vírgula separa parte fracionária, a confusão é comum. Uma string como "1.234,56" pode ser interpretada como mil duzentos e trinta e quatro inteiros e cinquenta e seis centésimos, o que tem sete dígitos inteiros. Mas se alguém ler como um separador decimal padrão americano, vira um número completamente diferente. O conselho prático é normalizar a entrada removendo caracteres não numéricos e só depois contar o tamanho, mas deixe claro nas especificações qual convenção está sendo usada.
Em termos de performance, a comparação em potências de dez costuma ser a opção mais rápida para inteiros. Em Python, por exemplo, len(str(n)) é confortável para uso geral, mas tem overhead de alocação de string e de conversão. Para chamadas repetidas dentro de loops apertados, a função com comparações diretas ou bit-manipulação em bases menores pode cortar o tempo de execução pela metade em benchmarks simples. Não é ganho astronômico, mas em sistemas que processam milhões de registros por segundo, a diferença aparece no monitor. Se o seu cenário envolve números arbitrariamente grandes, onde inteiros fixos não bastam, a estratégia lógica continua a mesma: evite ponto flutuante e use representação inteira. Em Python, inteiros têm precisão ilimitada, então a função com while n >= base: n //= 10; base *= 10 funciona sem surpresas. Em linguagens com tipos fixos, a verificação de estouro deve fazer parte da lógica antes da contagem.
Outro detalhe prático que eu aprendi na marra é que formatos de arquivo e APIs externas frequentemente chegam com zeros à esquerda quando o dado é tratado como texto. Um identificador como "0047" tem quatro caracteres, mas numericamente representa o número 47, que tem dois dígitos. Se você vai fazer a contagem para validação de formato, conte caracteres. Se for para lógica numérica, converta para inteiro primeiro. Misturar os dois entendimentos é a causa mais comum de bugs aqui. Para quem precisa de uma implementação direta, uma versão segura em pseudocódigo seria algo assim: trate zero separadamente; tome o valor absoluto de forma segura, preferindo conversão para tipo sem sinal quando possível; repita comparações com 10, 100, 1000, 10000 e assim por diante até ultrapassar o número; retorne o índice correspondente. Em código real, você pode ainda otimizar com tabelas menores, como intervalos pré-definidos para 32 e 64 bits, para eliminar laços em casos comuns.
Há também o caso dos logaritmos em bases diferentes. Em alguns ambientes científicos, você precisa contar dígitos em base 2 ou base 16, não em base 10. A mesma ideia de floor(log_b(n)) + 1 se aplica, mas ai você usa log2 ou log16. Em prática, contagem de bits costuma ser feita com built-ins de linguagem, como count-leading-zeros, que são instruiçoes de hardware e muito mais rápidas que qualquer loop. Resumindo sem dramatismo: a resposta para quantos algarismo formam o número n depende do tipo de entrada, do tratamento de borda e da decisão sobre o que conta como dígito. Evite log quando puder usar inteiros puros. Trate zero, negativo e overflow antes de pensar em performance. E leve a representação textual com seriedade, porque é ali que a maioria dos erros reais entra no sistema.