web-dev-qa-db-fra.com

Trouver la longueur d'un entier en C

J'aimerais savoir comment trouver la longueur d'un entier en C.

Par exemple:

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

etc.

Comment puis-je faire cela en C?

53
marabunta2048

C:

Pourquoi ne pas simplement prendre le journal en base 10 de la valeur absolue du nombre, l’arrondir en bas 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.

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

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

Vous devriez envelopper ceci dans une clause assurant que the_integer != 0, puisque log10(0) renvoie -HUGE_VAL conformément à man 3 log.

De plus, vous pouvez vouloir en ajouter un au résultat final si la saisie est négative, si la longueur du nombre et son signe négatif vous intéressent.

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 de la réponse de Kangkan pour une discussion sur l'efficacité.

91
Jordan Lewis

Si vous êtes intéressé par une solution rapide et très simple , voici ce qui pourrait ê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 que la solution la plus ingénieuse ne soit pas récompensée, il est trivial à comprendre et également trivial à mettre en œuvre - c'est donc rapide.

Sur un Q6600 utilisant MSC, j'ai comparé cela avec la boucle suivante:

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

Cette solution prend 0,062 seconde, la deuxième solution la plus rapide utilisée par Pete Kirkham utilisant une approche logarithmique intelligente prend 0,11 seconde, soit presque deux fois plus longtemps. Cependant, pour les nombres d'environ 10000 et moins, le journal intelligent est plus rapide.

Au détriment de la 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 coûte toujours 0,062 s pour les grands nombres et se dégrade à environ 0,09 s pour les plus petits nombres - plus rapidement dans les deux cas que l'approche par journal intelligent. (gcc crée un code plus rapide; 0,052 pour cette solution et 0,09 seconde pour l’approche intelligente).

44
Eamon Nerbonne
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;
}
24
zed_0xff

Vous pouvez écrire une fonction comme celle-ci:

unsigned numDigits(const unsigned n) {
    if (n < 10) return 1;
    return 1 + numDigits(n / 10);
}
18
Kangkan

longueur de n:

length =  ( i==0 ) ? 1 : (int)log10(n)+1;
10
Fritz G. Mehner

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: divisez la division en entier 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 renvoyer 1 si l'entier est 0 dans la première solution et vous pouvez également vouloir traiter les entiers négatifs (utilisez -x si x < 0).

7
IVlad

Oui, en utilisant sprintf.

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

Sinon, 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
Jamie Wong

Le moyen le plus efficace pourrait être d’utiliser une approche basée sur un logarithme rapide, similaire à celle utilisée pour déterminer le bit le plus élevé défini 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 seconde pour 20 millions d'appels sur mon netbook; la division itérative comme zed_0xff a 1,6, la division récursive comme Kangkan prend 1,8 et l'utilisation de fonctions à virgule flottante (le code de Jordan Lewis) prend 6,6 s L'utilisation de snprintf prend 11.5 secondes, mais vous donnera la taille requise par snprintf pour tous les formats, pas seulement pour les entiers. Jordan signale que les commandes ne sont pas conservées sur son processeur, qui effectue un virgule flottante plus rapidement 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
Pete Kirkham

Une implémentation snprintf correcte:

int count = snprintf(NULL, 0, "%i", x);
5
sam hocevar
int digits=1;

while (x>=10){
    x/=10;
    digits++;
}
return digits;
4
Pasi

Vous pouvez utiliser ceci -

(type_données) log10 (nom_variable) +1

ex: 

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

2
Ashraful
sprintf(s, "%d", n);
length_of_int = strlen(s);
1
OK_or_CANCEL

Assez facile

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
Mauro

continuez à diviser par dix jusqu'à obtenir zéro, puis indiquez 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
Graphics Noob

Ma façon:

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 est sa rapidité par rapport aux autres propositions.

0
tBlabs

Cela vaut pour les entiers négatifs et positifs

    int get_len(int n)
    {
        if(n == 0)
        return 1;

        if(n < 0)    
        {
           n = n * (-1); // if negative
        }

        return  log10(n) + 1;
    }

Même logique va pour la boucle

  int get_len(int n)
  {
       if(n == 0)
       return 1;

       int len = 0;
       if(n < 0)
       n = n * (-1);

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

       return len;
  }
0
Djolo
int returnIntLength(int value){
    int counter = 0;
    if(value < 0)
    {
        counter++;
        value = -value;
    }
    else if(value == 0)
        return 1;

    while(value > 0){
        value /= 10;
        counter++;
    }

    return counter;
}

Je pense que cette méthode est bien adaptée à cette tâche:

valeur et réponses:

  • -50 -> 3 // cela comptera - comme un caractère également si vous ne voulez pas compter moins puis retirez counter ++ de la 5ème ligne.

  • 566666 -> 6

  • 0 -> 1

  • 505 -> 3

0
Sa'gear Giree

Une façon plus verbeuse 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
Chirag M
int intlen(int integer){
    int a;
    for(a = 1; integer /= 10; a++);
    return a;
}
0
Ruza

Veuillez trouver ma réponse, c’est dans le code d’une ligne:

#include <stdio.h> int main(void){ int c = 12388884; printf("length of integer is: %d",printf("%d",c)); return 0; }

c'est simple et intelligent! Votez si vous aimez ça!

0
Nasir Shah

À mon avis, la solution la plus courte et la plus simple 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
Flo