C语言 在C中查找整数的长度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3068397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Finding the length of an integer in C
提问by marabunta2048
I would like to know how I can find the length of an integer in C.
我想知道如何在 C 中找到整数的长度。
For instance:
例如:
- 1 => 1
- 25 => 2
- 12512 => 5
- 0 => 1
- 1 => 1
- 25 => 2
- 12512 => 5
- 0 => 1
and so on.
等等。
How can I do this in C?
我怎样才能在 C 中做到这一点?
回答by Jordan Lewis
C:
C:
Why not just take the base-10 log of the absolute value of the number, round it down, and add one? This works for positive and negative numbers that aren't 0, and avoids having to use any string conversion functions.
为什么不直接取数字绝对值的以 10 为底的对数,将其四舍五入并加一?这适用于非 0 的正数和负数,并避免使用任何字符串转换函数。
The log10, abs, and floorfunctions are provided by math.h. For example:
的log10,abs和floor功能通过提供math.h。例如:
int nDigits = floor(log10(abs(the_integer))) + 1;
You should wrap this in a clause ensuring that the_integer != 0, since log10(0)returns -HUGE_VALaccording to man 3 log.
您应该将其包装在一个确保 的子句中the_integer != 0,因为根据log10(0)返回。-HUGE_VALman 3 log
Additionally, you may want to add one to the final result if the input is negative, if you're interested in the length of the number including its negative sign.
此外,如果您对数字的长度(包括其负号)感兴趣,如果输入为负,您可能希望在最终结果中加一。
Java:
爪哇:
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
N.B.The floating-point nature of the calculations involved in this method may cause it to be slower than a more direct approach. See the comments for Kangkan's answer for some discussion of efficiency.
注意此方法中涉及的计算的浮点性质可能会导致它比更直接的方法慢。有关效率的一些讨论,请参阅康坎回答的评论。
回答by Eamon Nerbonne
If you're interested in a fastand very simplesolution, the following might be quickest (this depends on the probability distribution of the numbers in 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);
}
While it might not win prizes for the most ingenious solution, it's trivial to understand and also trivial to execute - so it's fast.
虽然它可能不会因为最巧妙的解决方案而赢得奖品,但理解起来很简单,执行起来也很简单 - 所以它很快。
On a Q6600 using MSC I benchmarked this with the following loop:
在使用 MSC 的 Q6600 上,我使用以下循环对此进行了基准测试:
int res = 0;
for(int i = -2000000000; i < 2000000000; i += 200) res += printLen(i);
This solution takes 0.062s, the second-fastest solution by Pete Kirkham using a smart-logarithm approach takes 0.115s - almost twice as long. However, for numbers around 10000 and below, the smart-log is faster.
该解决方案需要 0.062 秒,Pete Kirkham 使用智能对数方法的第二快解决方案需要 0.115 秒 - 几乎是其两倍。但是,对于 10000 左右及以下的数字,智能日志更快。
At the expense of some clarity, you can more reliably beat smart-log (at least, on a Q6600):
以牺牲一些清晰度为代价,您可以更可靠地击败智能日志(至少在 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;
}
}
}
This solution is still 0.062s on large numbers, and degrades to around 0.09s for smaller numbers - faster in both cases than the smart-log approach. (gcc makes faster code; 0.052 for this solution and 0.09s for the smart-log approach).
这个解决方案在大数字上仍然是 0.062s,对于较小的数字会降级到 0.09s 左右 - 在这两种情况下都比智能日志方法更快。(gcc 生成更快的代码;此解决方案为 0.052,智能日志方法为 0.09s)。
回答by zed_0xff
int get_int_len (int value){
int l=1;
while(value>9){ l++; value/=10; }
return l;
}
and second one will work for negative numbers too:
第二个也适用于负数:
int get_int_len_with_negative_too (int value){
int l=!value;
while(value){ l++; value/=10; }
return l;
}
回答by Kangkan
You can write a function like this:
你可以写一个这样的函数:
unsigned numDigits(const unsigned n) {
if (n < 10) return 1;
return 1 + numDigits(n / 10);
}
回答by Fritz G. Mehner
length of n:
n 的长度:
length = ( i==0 ) ? 1 : (int)log10(n)+1;
回答by Pete Kirkham
The most efficient way could possibly be to use a fast logarithm based approach, similar to those used to determine the highest bit set in an integer.
最有效的方法可能是使用基于快速对数的方法,类似于用于确定整数中最高位集的方法。
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;
}
This (possibly premature) optimisation takes 0.65s for 20 million calls on my netbook; iterative division like zed_0xff has takes 1.6s, recursive division like Kangkan takes 1.8s, and using floating point functions (Jordan Lewis' code) takes a whopping 6.6s. Using snprintf takes 11.5s, but will give you the size that snprintf requires for any format, not just integers. Jordan reports that the ordering of the timings are not maintained on his processor, which does floating point faster than mine.
对于我的上网本上的 2000 万次调用,这种(可能是过早的)优化需要 0.65 秒;像zed_0xff这样的迭代除法需要1.6s,像Kangkan这样的递归除法需要1.8s,使用浮点函数(Jordan Lewis的代码)需要6.6s。使用 snprintf 需要 11.5 秒,但会为您提供 snprintf 对任何格式所需的大小,而不仅仅是整数。Jordan 报告说他的处理器没有维护时序的顺序,它的浮点运算速度比我的快。
The easiest is probably to ask snprintf for the printed length:
最简单的方法可能是向 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;
}
回答by IVlad
The number of digits of an integer xis equal to 1 + log10(x). So you can do this:
一个整数的位数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));
}
Or you can run a loop to count the digits yourself: do integer division by 10 until the number is 0:
或者您可以运行一个循环来自己计算数字:将整数除以 10,直到数字为 0:
int numDigits = 0;
do
{
++numDigits;
x = x / 10;
} while ( x );
You have to be a bit careful to return 1if the integer is 0in the first solution and you might also want to treat negative integers (work with -xif x < 0).
1如果整数0在第一个解决方案中,您必须小心返回,并且您可能还想处理负整数(使用-xif x < 0)。
回答by sam hocevar
A correct snprintfimplementation:
正确的snprintf实现:
int count = snprintf(NULL, 0, "%i", x);
回答by Jamie Wong
Yes, using sprintf.
是的,使用 sprintf。
int num;
scanf("%d",&num);
char testing[100];
sprintf(testing,"%d",num);
int length = strlen(testing);
Alternatively, you can do this mathematically using the log10function.
或者,您可以使用该log10函数以数学方式执行此操作。
int num;
scanf("%d",&num);
int length;
if (num == 0) {
length = 1;
} else {
length = log10(fabs(num)) + 1;
if (num < 0) length++;
}
回答by Pasi
int digits=1;
while (x>=10){
x/=10;
digits++;
}
return digits;

