quantos dígitos tem um número??

toblesu

Power Member
Boas...

Assim de repente deu-me uma branca.... precisava duma função análoga ao strlen() para saber o número de digítos de um inteiro.

já andei à procura, mas o mais provável é não ter efectuado bem a pesquisa!

Se me puderem desenrascar, facilitava-me muito, estou apertada com o tempo para continuar a fazer pesquisas sem sucesso! :(

Obrigado
 
Bom não sei que linguagem queres... Mas basta ires dividindo o número por 10 e fazendo o arredondamento ás unidades e com um contador vais incrementando, quando o número for 0 termina o ciclo...

EDIT: Quanto ao nome da função em si não sei qual será... mas visto ser um algoritmo de fácil implementação...
 
Última edição:
Matematicamente: floor( log10( inteiro ) ) + 1

ou seja, a parte inteira do logaritmo de base 10 do número inteiro do qual pretendes saber quantos algarismos tem, mais um

É um canhão para matar uma mosca mas é isto. Há outras coisas mais rápidas mas mais demoradas de explicar.
 
Última edição:
Se usares divisão inteira não há arredondamentos nem logaritmos à mistura. Não sei o que será mais eficiente, 10 divisões ou um logaritmo e dois casts... Depende...
Em C:
Código:
int dgtlen(int n)
{
    if(n == 0)
        return 1;
    else
    {
        int c;
        for(c = 0; n; n /= 10)
            c++;
        return c;
    }
}
 
Última edição:
nao penso que seja isso que ele pretende..

pelo que percebi

1234

e um numero com 4 digitos

logo

tenta converter para uma string e aplica o strlen

ou faz uma função porque nao acho que haja nenhuma na std lib de c
 
Se usares divisão inteira não há arredondamentos nem logaritmos à mistura. Não sei o que será mais eficiente, 10 divisões ou um logaritmo e dois casts... Depende...
Em C:
Código:
int dgtlen(int n)
{
    if(n == 0)
        return 1;
    else
    {
        int c;
        for(c = 0; n; n /= 10)
            c++;
        return c;
    }
}


Cheira-me que é mais as "n" divisões inteiras. Qual é a rapidez da instrução x86 DIV ou IDIV? :D Tirando algoritmos com look-up tables ou fazer as contas em base 2 com shifts e depois passar para base 10 (implica uma ou duas divisões em vírgula flutuante)... sei lá...

Depende do que se pretende. Em alguns casos até a opção INT->STRING ->STRLEN pode ser encarada. Depende da "pressão" :D
 
de facto é mesmo isso, posso nao ter sido muito explicito,
portando: 1234 -> 4 digitos.

tentei implementar a funcao que me deram mas não correu la muito bem.,....

vou ver melhor, mas a ideia é mesmo essa....

(estou a programar em c++)


mais uma vez, obrigado!
 
Cheira-me que é mais as "n" divisões inteiras. Qual é a rapidez da instrução x86 DIV ou IDIV? :D Tirando algoritmos com look-up tables ou fazer as contas em base 2 com shifts e depois passar para base 10 (implica uma ou duas divisões em vírgula flutuante)... sei lá...

Depende do que se pretende. Em alguns casos até a opção INT->STRING ->STRLEN pode ser encarada. Depende da "pressão" :D
Se o número em questão for, por exemplo, um googol (n = 10^100, mais que o número de partículas subatómicas no universo observável), são 101 dígitos, logo 101 divisões e não 10^100!
Numa máquina de 32 bits só consegues representar números até 2^32, que tem 10 dígitos. Numa de 64 bits, são 20 dígitos. Logo, na pior das hipóteses, 20 divisões, 20 incrementos e 21 comparações. Nada mau...

Com logaritmos... Bem, calcular logaritmos implica o uso de vírgula flutuante, logo cast para float/double e cast para inteiro no fim. O que é complicado é o logaritmo. Não sei como será calculado numa FPU actual, mas de certeza que é uma operação mais pesada que divisões.

Mas, qualquer destas duas situações funciona completamente dentro do processador, porque podem ser executadas apenas em registos.

Agora, fazer uma string implica acesso à memória. Pois, enquanto escreves a string na memória, o processador tem tempo para fazer as divisões todas ou até mesmo o cálculo do logaritmo. Depois ainda tens de contar os caracteres...

E... para fazer a string a partir de um inteiro usa-se um algoritmo semelhante ao que eu apresentei...

Peço desculpa pelo core dump...
 
Última edição:
Quando disse "n" divisões era no sentido de ser um determinado número de divisões e não um valor igual ao inteiro do qual se pretende saber quantos dígitos tem. Creio que contextualizaste o meu post no seguimento do teu post com o algoritmo onde usas a variável n.

Como sabes, no mundo académico quando se usa o jargão "n" coisas é no sentido de ser um número inteiro e finito de "coisas".

Mas fizeste bem em esclarecer.
 
Nao vou por a linguagem exacta mas ca vai a teoria.


Código:
scanf("%d",n);

while(n>=1)
{
i++;
n=n/10
}

printf("%d", i);


penso ser assim, nao tenho o c no pc por isso n posso testar, mas penso que seja assim.
espero ter ajudado
cumpz
 
Última edição pelo moderador:
O algortimo do logaritmo é complexo e certamente que os casts são o menos importante.

A história com a string é apenas uma curiosidade.

O algoritmo onde se vai sucessivamente dividindo o inteiro por 10 é o menos pesado e mais "natural". As operações mais pesadas vão ser os DIV/IDIV (x86) que comparado com o resto são gotinhas.
Se quiseres optimizar o teu algoritmo opta por um método de busca mais inteligente. O código é simples. Se quiseres fazê-lo como exercício a ideia é:

Imagina que sabes que o teu inteiro não tem mais do 8 algarismos

supõe que o inteiro a sondar é o 00234142 (meti zeros à esquerda para lembrar que admitimos que o limite é de 8 algarismos)
ora este número tem 6 algarismos. Um algoritmo diferente seria...
Divides (divisão inteira) primeiro 10^4 (10000), se for zero o número tem menos de 4 algarimos, se for diferente de zero tem mais. No exemplo caso a divisão não seria zero logo saberiamos que tem mais de 4 algarismos. Em seguida divides o resultado da divisão anterior por 10^2 e seguirias a mesma lógica. Nesta segunda divisão o resultado seria zero logo ficarias a saber que o inteiro tem menos de 7 e mais de 4. Em seguida pegas no resto e continuas o raciocínio com uma divisão por 10^1. Se o resultado for zero então o número teria 5 algarismos, se for diferente de zero então é porque o número inteiro original tem 6 algarismos.

Se o número máximo de algarismos for por exemplo 16, só terás de dividir em qq dos casos por 10^8, 10^4, 10^2, 10^1, ou seja, Log2(número de algarismos) divisões
 
Última edição:
que volta!!!

alguém já experimentou a minha maneira?? penso que esteja correcta, e sem funções, torna um pouco mais rápido o processamento
 
Bastava converter o inteiro para string, e depois obter o length. Cria uma função que depois faz o return do resultado.

Convinha ler os posts anteriores. Já foi avançada essa solução e dito por um membro que:

Agora, fazer uma string implica acesso à memória. Pois, enquanto escreves a string na memória, o processador tem tempo para fazer as divisões todas ou até mesmo o cálculo do logaritmo. Depois ainda tens de contar os caracteres...

E... para fazer a string a partir de um inteiro usa-se um algoritmo semelhante ao que eu apresentei...

Obviamente que dá para fazer como indicas mas deve ser umas 100x mais lento que, por exemplo, as divisões inteiras por 10
Se o que é pretendido é algo simples e fácil de programar sem qq relevância para a rapidez do método então encontras igualmente uns posts atrás outra solução trivial:

Matematicamente: floor( log10( inteiro ) ) + 1


Podes ir a pé até Madrid mas de carro é melhor.
 
Última edição:
Já tou a ver muita gente que não lê os posts anteriores...

E que tal a solução mais estúpida de todas?

Código:
int dgtlen(int n)
{
    if(n<0) n = -n;
    return n<10?1:
             n<100?2:
             n<1000?3:
             n<10000?4:
             n<100000?5:
             n<1000000?6:
             n<10000000?7:
             n<100000000?8:
             n<1000000000?9:
             10;
}

Não é tão elegante, mas de certeza que é a mais eficiente...:002:
 
Back
Topo