80

我想知道如何在 C 中找到整数的长度。

例如:

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

等等。

我怎样才能在 C 中做到这一点?

4

29 回答 29

122

C:

为什么不直接取数字绝对值的以 10 为底的对数,四舍五入再加一呢?这适用于非 0 的正数和负数,并且避免了必须使用任何字符串转换函数。

log10和函数由提供abs。例如:floormath.h

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

您应该将其包装在一个子句中,以确保the_integer != 0, since根据log10(0)返回。-HUGE_VALman 3 log

此外,如果输入为负数,如果您对数字的长度(包括其负号)感兴趣,您可能希望在最终结果中加一。

爪哇:

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

注意此方法中涉及的计算的浮点性质可能会导致它比更直接的方法慢。有关效率的一些讨论,请参阅康坎回答的评论。

于 2010-06-18T09:13:47.250 回答
54

如果您对快速非常简单的解决方案感兴趣,以下可能是最快的(这取决于相关数字的概率分布):

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);
}

虽然它可能不会因为最巧妙的解决方案而获奖,但理解起来很简单,执行起来也很简单——所以它很快。

在使用 MSC 的 Q6600 上,我使用以下循环对此进行了基准测试:

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

该解决方案耗时 0.062 秒,Pete Kirkham 使用智能对数方法的第二快解决方案耗时 0.115 秒 - 几乎是两倍。但是,对于 10000 及以下的数字,智能日志更快。

以牺牲一些清晰度为代价,您可以更可靠地击败智能日志(至少在 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;
        }
    }
}

这个解决方案在大数字上仍然是 0.062 秒,对于较小的数字会降到 0.09 秒左右——在这两种情况下都比智能日志方法快。(gcc 生成更快的代码;此解决方案为 0.052,智能日志方法为 0.09s)。

于 2010-06-18T12:33:39.137 回答
37
int get_int_len (int value){
  int l=1;
  while(value>9){ l++; value/=10; }
  return l;
}

第二个也适用于负数:

int get_int_len_with_negative_too (int value){
  int l=!value;
  while(value){ l++; value/=10; }
  return l;
}
于 2010-06-18T09:11:44.380 回答
18

你可以写一个这样的函数:

unsigned numDigits(const unsigned n) {
    if (n < 10) return 1;
    return 1 + numDigits(n / 10);
}
于 2010-06-18T09:12:52.953 回答
12

n的长度:

length =  ( i==0 ) ? 1 : (int)log10(n)+1;
于 2010-06-18T09:14:25.747 回答
8

正确的snprintf实现:

int count = snprintf(NULL, 0, "%i", x);
于 2011-04-09T12:15:41.130 回答
7

整数的位数x等于1 + log10(x)。所以你可以这样做:

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

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

或者您可以运行一个循环来自己计算数字:将整数除以 10,直到数字为 0:

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

1如果整数在第一个解决方案中,您必须小心返回0,并且您可能还想处理负整数(使用-xif x < 0)。

于 2010-06-18T09:14:05.563 回答
7

最有效的方法可能是使用基于快速对数的方法,类似于用于确定整数中最高位集的方法。

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;
}

这种(可能为时过早的)优化需要 0.65 秒才能在我的上网本上进行 2000 万次调用;像 zed_0xff 这样的迭代除法需要 1.6 秒,像康坎这样的递归除法需要 1.8 秒,使用浮点函数(Jordan Lewis 的代码)需要高达 6.6 秒。使用 snprintf 需要 11.5 秒,但会给您 snprintf 任何格式所需的大小,而不仅仅是整数。乔丹报告说,他的处理器没有维护时序的顺序,它的浮点运算速度比我的快。

最简单的可能是向 snprintf 询问打印的长度:

#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;
}
于 2010-06-18T09:16:21.503 回答
6

是的,使用 sprintf。

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

或者,您可以使用该log10函数以数学方式执行此操作。

int num;
scanf("%d",&num);
int length;
if (num == 0) {
  length = 1;
} else {    
  length = log10(fabs(num)) + 1;
  if (num < 0) length++;
}
于 2010-06-18T09:10:24.353 回答
5
int digits=1;

while (x>=10){
    x/=10;
    digits++;
}
return digits;
于 2015-02-14T08:22:55.530 回答
2
sprintf(s, "%d", n);
length_of_int = strlen(s);
于 2010-06-18T09:31:25.143 回答
2

你可以用这个——

(data_type)log10(variable_name)+1

前任:

len = (int)log10(数字)+1;

于 2017-01-31T07:42:55.377 回答
2

在这个问题中,我使用了一些算术解决方案。谢谢 :)

int main(void)
{
    int n, x = 10, i = 1;
    scanf("%d", &n);
    while(n / x > 0)
    {
        x*=10;
        i++;
    }
    printf("the number contains %d digits\n", i);

    return 0;
}
于 2020-12-05T21:38:15.797 回答
1

非常简单

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;
}
于 2010-06-18T09:11:36.970 回答
1

继续除以十,直到你得到零,然后输出除数。

int intLen(int x)
{
  if(!x) return 1;
  int i;
  for(i=0; x!=0; ++i)
  {
    x /= 10;
  }
  return i;
}
于 2010-06-18T09:13:09.603 回答
1

这适用于消极和积极的intigers

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

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

        return  log10(n) + 1;
    }

同样的逻辑也适用于循环

  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;
  }
于 2018-10-23T22:15:34.303 回答
1

对于简单的程序...

int num = 456, length=0 // or read value from the user to num
while(num>0){
    num=num/10;
    length++;
}

使用另一个变量来保留初始num值。

于 2021-10-06T14:04:19.633 回答
1

为什么不将整数转换为 String 并获得这样的长度:

int data = 123;
int data_len = String(data).length();
于 2021-02-02T17:36:04.320 回答
0

In my opinion the shortest and easiest solution would be:

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);
于 2014-01-04T15:07:56.393 回答
0
int intlen(int integer){
    int a;
    for(a = 1; integer /= 10; a++);
    return a;
}
于 2014-10-26T20:06:20.903 回答
0

我的方式:

只要数字不能被 10 整除,就除以:

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

    return i;
}

我不知道它与其他命题相比有多快。

于 2014-09-12T07:13:47.413 回答
0

更详细的方法是使用此功能。

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;
}
于 2018-08-18T07:14:44.667 回答
0

解决方案

使用整数长度变化的限制,在十进制的情况下它是 10 的幂,因此每次验证指定的整数没有超过限制时使用一个计数器。

math.h依赖:

#include <math.h>

int count_digits_of_integer(unsigned int integer) {
    int count = 1;

    while(1) {
        int limit = pow(10, count);
        if(integer < limit) break;
        count++;

    }

    return count;
}

无依赖:

int int_pow(int base, int exponent) {
    int potency = base;

    for(int i = 1; i < exponent; i++) potency *= base;

    return potency;

}

int count_digits_of_integer(unsigned int integer) {
    int count = 1;
    
    while(1) {
        int limit = int_pow(10, count);
        if(integer < limit) break;
        count++;

    }
    
    return count;
}

执行

#include <stdio.h>

// Copy and paste the solution code here

int main() {
    
    printf("%i -> (%i digits)\n", 0, count_digits_of_integer(0));
    printf("%i -> (%i digits)\n", 12, count_digits_of_integer(12));
    printf("%i -> (%i digits)\n", 34569, count_digits_of_integer(34569));
    printf("%i -> (%i digits)\n", 1234, count_digits_of_integer(1234));
    printf("%i -> (%i digits)\n", 3980000, count_digits_of_integer(3980000));
    printf("%i -> (%i digits)\n", 100, count_digits_of_integer(100));
    printf("%i -> (%i digits)\n", 9, count_digits_of_integer(9));
    printf("%i -> (%i digits)\n", 385784, count_digits_of_integer(385784));
    
    return 0;
}

输出:

0 -> (1 digits)
12 -> (2 digits)
34569 -> (5 digits)
1234 -> (4 digits)
3980000 -> (7 digits)
100 -> (3 digits)
9 -> (1 digits)
385784 -> (6 digits)
于 2021-10-16T01:50:00.667 回答
0

嗯,大概是这样……?

#define _LEN(x) (sizeof(#x)/sizeof(char)-1)
于 2022-02-09T04:24:22.013 回答
0
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;
}

我认为这种方法非常适合这项任务:

价值和答案:

  • -50 -> 3 //如果你不想减号,它也会算作一个字符,然后从第 5 行删除 counter++。

  • 566666 -> 6

  • 0 -> 1

  • 505 -> 3

于 2018-12-25T07:04:00.813 回答
-1

我想我找到了找到整数长度的最有效方法,这是一种非常简单而优雅的方法:

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".
}
于 2013-05-19T06:56:23.923 回答
-1

int main(void){ unsigned int n, size=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;

}

于 2018-09-13T04:04:23.733 回答
-1
// Variables 

long c = 2222882;
long b = c;
float x = 10;
int length = 0;

//Loop to know the length

    for(int i = 0; b != 0; i++)
    {
        b = (float) c / x;
        x = x*10;
        length++;
    }
//Print this one
    printf("%i", length);
于 2021-04-23T17:30:25.493 回答
-2

请在一行代码中找到我的答案:

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

这是简单而聪明的!喜欢这个就点个赞吧!

于 2019-01-08T06:11:40.000 回答