我担心这个问题有一个简单而明显的答案。我需要确定一个项目的数量有多少位宽,以便我可以用保持对齐所需的最少前导零数填充每个项目编号。例如,如果总数 < 10,我不想要前导零,如果总数在 10 到 99 之间,我想要 1,等等。
一种解决方案是将项目计数转换为字符串,然后计数字符。呸!有没有更好的办法?
编辑:我不会想到使用常用对数(我不知道存在这样的东西)。所以,对我来说并不明显——但绝对简单。
这应该这样做:
int length = (number ==0) ? 1 : (int)Math.log10(number) + 1;
int length = (int)Math.Log10(Math.Abs(number)) + 1;
您可能需要考虑负号..
如果语句具有乘法...例如(其中 n 是需要其位数的数字),则将重复比重复除法更有效的解决方案
unsigned int test = 1;
unsigned int digits = 0;
while (n >= test)
{
++digits;
test *= 10;
}
如果项目计数有一些合理的上限(例如,无符号整数的 32 位范围),那么更好的方法是与某个静态数组的成员进行比较,例如
// this covers the whole range of 32-bit unsigned values
const unsigned int test[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
unsigned int digits = 10;
while(n < test[digits]) --digits;
您可以使用 while 循环,它可能比对数更快,因为它仅使用整数算术:
int len = 0;
while (n > 0) {
len++;
n /= 10;
}
我把它作为练习留给读者来调整这个算法来处理零和负数。
如果您要在.Net中填充数字,那么
num.ToString().PadLeft(10, '0')
可能会做你想做的事。
我会发表评论,但我的代表分数不会让我有这种区别。
我想指出的是,尽管 Log(10) 是一种非常优雅(阅读:代码行数很少)的解决方案,但它可能是对处理器负担最重的解决方案。
我认为 jherico 的回答可能是最有效的解决方案,因此应该得到奖励。
特别是如果你要为很多数字这样做..
由于数字没有前导零,因此您无论如何都要转换以添加它们。我不确定您为什么要如此努力地避免它来找到最终结果无论如何都必须是字符串的长度。
以 10 为底的对数提供了一种解决方案,有点矫枉过正。
可以循环10次删除,计算循环次数;
int num = 423;
int minimum = 1;
while (num > 10) {
num = num/10;
minimum++;
}
好吧,我无法抗拒:使用/=
:
#include <stdio.h>
int
main(){
int num = 423;
int count = 1;
while( num /= 10)
count ++;
printf("Count: %d\n", count);
return 0;
}
534 $ gcc count.c && ./a.out
Count: 3
535 $