Jor*_*wis 98
为什么不直接取数字的绝对值的基数10日志,将其四舍五入,并添加一个?这适用于非0的正数和负数,并且避免必须使用任何字符串转换函数.
这些log10
,abs
和floor
函数由提供math.h
.例如:
int nDigits = floor(log10(abs(the_integer))) + 1;
Run Code Online (Sandbox Code Playgroud)
你应该将它包装在一个条款中,确保the_integer != 0
,因为log10(0)
返回-HUGE_VAL
根据man 3 log
.
此外,如果输入为负数,您可能希望在最终结果中添加一个,如果您对数字的长度感兴趣,包括其负号.
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
Run Code Online (Sandbox Code Playgroud)
NB此方法涉及的计算的浮点性质可能导致它比更直接的方法更慢.有关效率的一些讨论,请参阅Kangkan答案的评论.
Eam*_*nne 45
如果您对快速且非常简单的解决方案感兴趣,以下可能是最快的(这取决于相关数字的概率分布):
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);
}
Run Code Online (Sandbox Code Playgroud)
虽然它可能无法为最巧妙的解决方案赢得奖品,但理解并轻松执行是微不足道的 - 所以它很快.
在使用MSC的Q6600上,我使用以下循环对此进行了基准测试:
int res = 0;
for(int i = -2000000000; i < 2000000000; i += 200) res += printLen(i);
Run Code Online (Sandbox Code Playgroud)
这个解决方案需要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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于较大的数字,此解决方案仍为0.062秒,对于较小的数字,此解决方案降至约0.09秒 - 两种情况下都比智能对数方法更快.(gcc使代码更快;此解决方案为0.052,智能对数方法为0.09).
zed*_*xff 26
int get_int_len (int value){
int l=1;
while(value>9){ l++; value/=10; }
return l;
}
Run Code Online (Sandbox Code Playgroud)
第二个也适用于负数:
int get_int_len_with_negative_too (int value){
int l=!value;
while(value){ l++; value/=10; }
return l;
}
Run Code Online (Sandbox Code Playgroud)
Kan*_*kan 18
你可以写一个这样的函数:
unsigned numDigits(const unsigned n) {
if (n < 10) return 1;
return 1 + numDigits(n / 10);
}
Run Code Online (Sandbox Code Playgroud)
Fri*_*ner 11
n的长度:
length = ( i==0 ) ? 1 : (int)log10(n)+1;
Run Code Online (Sandbox Code Playgroud)
整数的位数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));
}
Run Code Online (Sandbox Code Playgroud)
或者你可以运行一个循环来自己计算数字:整数除以10,直到数字为0:
int numDigits = 0;
do
{
++numDigits;
x = x / 10;
} while ( x );
Run Code Online (Sandbox Code Playgroud)
1
如果整数0
在第一个解决方案中并且您可能还想要处理负整数(使用-x
if x < 0
),则必须要小心返回.
最有效的方法可能是使用基于快速对数的方法,类似于用于确定整数中最高位集的方法.
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;
}
Run Code Online (Sandbox Code Playgroud)
这个(可能是不成熟的)优化需要0.65秒才能在我的上网本上拨打2000万个电话; 像zed_0xff这样的迭代划分需要1.6s,像Kangkan这样的递归划分需要1.8s,并且使用浮点函数(Jordan Lewis的代码)需要高达6.6s.使用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;
}
Run Code Online (Sandbox Code Playgroud)
是的,使用sprintf.
int num;
scanf("%d",&num);
char testing[100];
sprintf(testing,"%d",num);
int length = strlen(testing);
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用该log10
函数以数学方式执行此操作.
int num;
scanf("%d",&num);
int length;
if (num == 0) {
length = 1;
} else {
length = log10(fabs(num)) + 1;
if (num < 0) length++;
}
Run Code Online (Sandbox Code Playgroud)
小智 5
int digits=1;
while (x>=10){
x/=10;
digits++;
}
return digits;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
173582 次 |
最近记录: |