Trouver la longueur d'un entier en C

Je voudrais savoir comment je peux trouver la longueur d'un entier en C.

Par exemple:

  • 1 => 1
  • 25 => 2
  • 12512 => 5
  • 0 => 1

Et ainsi de suite.

Comment puis-je faire cela en C?

50
demandé sur APerson 2010-06-18 13:08:49

20 réponses

C:

Pourquoi ne pas simplement prendre le journal de base-10 de la valeur absolue du nombre, l'arrondir et en ajouter un? Cela fonctionne pour les nombres positifs et négatifs qui ne sont pas 0, et évite d'avoir à utiliser des fonctions de conversion de chaîne.

Le log10, abs, et floor fonctions sont fournies par math.h. Par exemple:

int nDigits = floor(log10(abs(the_integer))) + 1;

Vous devriez envelopper cela dans une clause garantissant que the_integer != 0, puisque log10(0) renvoie -HUGE_VAL selon man 3 log.

De plus, vous pouvez en ajouter un au résultat final si l'entrée est négative, si vous êtes intéressé par la longueur du nombre, y compris son signe négatif.

Java:

int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;

N.B. la nature à virgule flottante des calculs impliqués dans cette méthode peut la rendre plus lente qu'une approche plus directe. Voir les commentaires pour la réponse de Kangkan pour une discussion sur l'efficacité.

89
répondu Jordan Lewis 2015-04-20 23:32:23

Si vous êtes intéressé par une solution rapide et très simple, ce qui suit peut être le plus rapide (cela dépend de la distribution de probabilité des nombres en question):

int lenHelper(unsigned x) {
    if (x >= 1000000000) return 10;
    if (x >= 100000000)  return 9;
    if (x >= 10000000)   return 8;
    if (x >= 1000000)    return 7;
    if (x >= 100000)     return 6;
    if (x >= 10000)      return 5;
    if (x >= 1000)       return 4;
    if (x >= 100)        return 3;
    if (x >= 10)         return 2;
    return 1;
}

int printLen(int x) {
    return x < 0 ? lenHelper(-x) + 1 : lenHelper(x);
}

Bien qu'il puisse ne pas gagner de prix pour la solution la plus ingénieuse, il est trivial à comprendre et aussi trivial à exécuter - donc c'est rapide.

Sur un Q6600 en utilisant MSC I benchmarked ceci avec la boucle suivante:

int res = 0;
for(int i = -2000000000; i < 2000000000; i += 200) res += printLen(i);

Cette solution prend 0,062 s, la deuxième solution la plus rapide par Pete Kirkham en utilisant une approche smart-logarithme prend 0,115 s-presque deux fois plus longtemps. Cependant, pour les nombres autour de 10000 et ci-dessous, le Smart-log est plus rapide.

Au détriment d'une certaine clarté, vous pouvez battre de manière plus fiable smart-log (au moins, sur un Q6600):

int lenHelper(unsigned x) { 
    // this is either a fun exercise in optimization 
    // or it's extremely premature optimization.
    if(x >= 100000) {
        if(x >= 10000000) {
            if(x >= 1000000000) return 10;
            if(x >= 100000000) return 9;
            return 8;
        }
        if(x >= 1000000) return 7;
        return 6;
    } else {
        if(x >= 1000) {
            if(x >= 10000) return 5;
            return 4;
        } else {
            if(x >= 100) return 3;
            if(x >= 10) return 2;
            return 1;
        }
    }
}

Cette solution est toujours de 0,062 s sur les grands nombres, et se dégrade à environ 0,09 s pour les petits nombres - plus rapidement dans les deux cas que l'approche smart-log. (gcc rend le code plus rapide; 0.052 pour cette solution et 0.09 s pour le approche Smart-log).

42
répondu Eamon Nerbonne 2018-06-22 17:02:34
int get_int_len (int value){
  int l=1;
  while(value>9){ l++; value/=10; }
  return l;
}

Et le second fonctionnera aussi pour les nombres négatifs:

int get_int_len_with_negative_too (int value){
  int l=!value;
  while(value){ l++; value/=10; }
  return l;
}
23
répondu zed_0xff 2010-06-18 09:29:24

, Vous pouvez écrire une fonction comme ceci:

unsigned numDigits(const unsigned n) {
    if (n < 10) return 1;
    return 1 + numDigits(n / 10);
}
18
répondu Kangkan 2010-06-18 09:12:52

Longueur de n:

length =  ( i==0 ) ? 1 : (int)log10(n)+1;
10
répondu Fritz G. Mehner 2014-11-10 09:28:08

Oui, en utilisant sprintf.

int num;
scanf("%d",&num);
char testing[100];
sprintf(testing,"%d",num);
int length = strlen(testing);

Alternativement, vous pouvez le faire mathématiquement en utilisant la fonction log10.

int num;
scanf("%d",&num);
int length;
if (num == 0) {
  length = 1;
} else {    
  length = log10(fabs(num)) + 1;
  if (num < 0) length++;
}
7
répondu Jamie Wong 2010-06-18 09:10:24

Le nombre de chiffres d'un entier x est égal à 1 + log10(x). Donc, vous pouvez faire ceci:

#include <math.h>
#include <stdio.h>

int main()
{
    int x;
    scanf("%d", &x);
    printf("x has %d digits\n", 1 + (int)log10(x));
}

Ou vous pouvez exécuter une boucle pour compter les chiffres vous-même: faites la division entière par 10 jusqu'à ce que le nombre soit 0:

int numDigits = 0;
do
{
    ++numDigits;
    x = x / 10;
} while ( x );

, Vous devez être un peu prudent pour retourner 1 si l'entier est 0 dans la première solution et vous pouvez également traiter des entiers négatifs (travail avec -x si x < 0).

7
répondu IVlad 2010-06-18 09:14:05

Le moyen le plus efficace pourrait être d'utiliser une approche basée sur un logarithme rapide, similaire à celles utilisées pour déterminer le bit le plus élevé dans un entier.

size_t printed_length ( int32_t x )
{
    size_t count = x < 0 ? 2 : 1;

    if ( x < 0 ) x = -x;

    if ( x >= 100000000 ) {
        count += 8;
        x /= 100000000;
    }

    if ( x >= 10000 ) {
        count += 4;
        x /= 10000;
    }

    if ( x >= 100 ) {
        count += 2;
        x /= 100;
    }

    if ( x >= 10 )
        ++count;

    return count;
}

Cette optimisation (peut-être prématurée) prend 0,65 s pour 20 millions d'appels sur mon netbook; la division itérative comme zed_0xff prend 1,6 s, la division récursive comme Kangkan prend 1,8 s, et l'utilisation de fonctions à virgule flottante (code de Jordan Lewis) prend 6,6 S. utiliser snprintf prend 11,5 s, mais vous donnera snprintf nécessite pour n'importe quel format, pas seulement des entiers. Jordan rapporte que l'ordre des timings ne sont pas maintenus sur son processeur, ce qui fait le point flottant plus vite que le mien.

Le plus simple est probablement de demander à snprintf la longueur imprimée:

#include <stdio.h>

size_t printed_length ( int x )
{
    return snprintf ( NULL, 0, "%d", x );
}

int main ()
{
    int x[] = { 1, 25, 12512, 0, -15 };

    for ( int i = 0; i < sizeof ( x ) / sizeof ( x[0] ); ++i )
        printf ( "%d -> %d\n", x[i], printed_length ( x[i] ) );

    return 0;
}
6
répondu Pete Kirkham 2010-06-18 10:05:37

Une implémentation snprintf correcte:

int count = snprintf(NULL, 0, "%i", x);
5
répondu sam hocevar 2011-04-09 12:15:41
int digits=1;

while (x>=10){
    x/=10;
    digits++;
}
return digits;
4
répondu Pasi 2015-02-14 10:16:41

Vous pouvez utiliser ceci -

(data_type)log10(nom_variable)+1

Ex:

Len = (int)log10(nombre)+1;

2
répondu Ashraful 2017-01-31 07:42:55

Assez simple

int main() {
    int num = 123;
    char buf[50];

    // convert 123 to string [buf]
    itoa(num, buf, 10);

    // print our string
    printf("%s\n", strlen (buf));

    return 0;
}
1
répondu Mauro 2010-06-18 09:13:49
sprintf(s, "%d", n);
length_of_int = strlen(s);
1
répondu OK_or_CANCEL 2011-08-29 05:50:41

Continuez à diviser par dix jusqu'à ce que vous obteniez zéro, puis affichez simplement le nombre de divisions.

int intLen(int x)
{
  if(!x) return 1;
  int i;
  for(i=0; x!=0; ++i)
  {
    x /= 10;
  }
  return i;
}
0
répondu Graphics Noob 2010-06-18 09:29:59

Je pense avoir le moyen le plus efficace de trouver la longueur d'un entier c'est une manière très simple et élégante ici, il est:

int PEMath::LengthOfNum(int Num)
{
int count = 1;  //count starts at one because its the minumum amount of digits posible
if (Num < 0)
{
    Num *= (-1);
}

for(int i = 10; i <= Num; i*=10)
{
     count++;
}      
return count;
                // this loop will loop until the number "i" is bigger then "Num"
                // if "i" is less then "Num" multiply "i" by 10 and increase count
                // when the loop ends the number of count is the length of "Num".
}
0
répondu shiups 2013-05-19 07:17:24

À mon avis, la solution la plus courte et la plus facile serait:

int length , n;

printf("Enter a number: ");

scanf("%d", &n);

length = 0;

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

printf("Length of the number: %d", length);
0
répondu Flo 2014-01-10 08:14:33

Mon chemin:

Diviser tant que le nombre n'est plus divisible par 10:

u8 NumberOfDigits(u32 number)
{
    u8 i = 1;
    while (number /= 10) i++;

    return i;
}

Je ne sais pas à quelle vitesse est-ce en comparaison avec d'autres propositions..

0
répondu tBlabs 2014-09-12 07:13:47
int intlen(int integer){
    int a;
    for(a = 1; integer /= 10; a++);
    return a;
}
0
répondu Ruza 2014-10-26 20:06:20

Plus verbeux serait d'utiliser cette fonction.

int length(int n)
{
    bool stop;
    int nDigits = 0;
    int dividend = 1;
    do
    {
        stop = false;
        if (n > dividend)
        {
            nDigits = nDigits + 1;
            dividend = dividend * 10;
        }
        else {
            stop = true;
        }


    }
    while (stop == false);
    return nDigits;
}
0
répondu Chirag M 2018-08-18 07:14:44

INT main (void){ unsigned int n, taille=0;

printf("get the int:");
scanf("%u",&n);

/*the magic*/
for(int i = 1; n >= i; i*=10){
    size++;
}

printf("the value is: %u \n", n);
printf("the size is: %u \n", size);

return 0;

}

0
répondu p1r0 2018-09-13 04:04:23