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?
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é.
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).
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;
}
, Vous pouvez écrire une fonction comme ceci:
unsigned numDigits(const unsigned n) {
if (n < 10) return 1;
return 1 + numDigits(n / 10);
}
Longueur de n:
length = ( i==0 ) ? 1 : (int)log10(n)+1;
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++;
}
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
).
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;
}
Une implémentation snprintf
correcte:
int count = snprintf(NULL, 0, "%i", x);
Vous pouvez utiliser ceci -
(data_type)log10(nom_variable)+1
Ex:
Len = (int)log10(nombre)+1;
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;
}
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;
}
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".
}
À 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);
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..
int intlen(int integer){
int a;
for(a = 1; integer /= 10; a++);
return a;
}
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;
}
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;
}