有没有比这个方法更简洁的方法来获取整数的位数?
int numDigits = String.valueOf(1000).length();
有没有比这个方法更简洁的方法来获取整数的位数?
int numDigits = String.valueOf(1000).length();
当前回答
我在看了Integer.java源代码后写了这个函数。
private static int stringSize(int x) {
final int[] sizeTable = {9, 99, 999, 9_999, 99_999, 999_999, 9_999_999,
99_999_999, 999_999_999, Integer.MAX_VALUE};
for (int i = 0; ; ++i) {
if (x <= sizeTable[i]) {
return i + 1;
}
}
}
其他回答
我能试试吗?;)
基于德克的解决方案
final int digits = number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
计算int变量中数字数的有效方法之一是定义一个方法digitsCounter,其中包含所需数量的条件语句。 方法很简单,我们将检查n位数字所在的每个范围: 0: 9为个位数 10:99是两位数 100: 999是三位数等等……
static int digitsCounter(int N)
{ // N = Math.abs(N); // if `N` is -ve
if (0 <= N && N <= 9) return 1;
if (10 <= N && N <= 99) return 2;
if (100 <= N && N <= 999) return 3;
if (1000 <= N && N <= 9999) return 4;
if (10000 <= N && N <= 99999) return 5;
if (100000 <= N && N <= 999999) return 6;
if (1000000 <= N && N <= 9999999) return 7;
if (10000000 <= N && N <= 99999999) return 8;
if (100000000 <= N && N <= 999999999) return 9;
return 10;
}
一种更干净的方法是取消下限检查,因为如果我们按顺序进行,就不需要下限检查了。
static int digitsCounter(int N)
{
N = N < 0 ? -N : N;
if (N <= 9) return 1;
if (N <= 99) return 2;
if (N <= 999) return 3;
if (N <= 9999) return 4;
if (N <= 99999) return 5;
if (N <= 999999) return 6;
if (N <= 9999999) return 7;
if (N <= 99999999) return 8;
if (N <= 999999999) return 9;
return 10; // Max possible digits in an 'int'
}
Two comments on your benchmark: Java is a complex environment, what with just-in-time compiling and garbage collection and so forth, so to get a fair comparison, whenever I run a benchmark, I always: (a) enclose the two tests in a loop that runs them in sequence 5 or 10 times. Quite often the runtime on the second pass through the loop is quite different from the first. And (b) After each "approach", I do a System.gc() to try to trigger a garbage collection. Otherwise, the first approach might generate a bunch of objects, but not quite enough to force a garbage collection, then the second approach creates a few objects, the heap is exhausted, and garbage collection runs. Then the second approach is "charged" for picking up the garbage left by the first approach. Very unfair!
也就是说,上述两种方法在本例中都没有产生显著差异。
不管有没有这些修改,我得到的结果和你完全不同。当我运行这个时,是的,toString方法给出的运行时间为6400到6600 millis,而log方法给出的运行时间为20,000到20,400 millis。对数方法对我来说不是稍微快一点,而是慢了3倍。
请注意,这两种方法涉及非常不同的代价,所以这并不完全令人震惊:toString方法将创建许多必须清理的临时对象,而log方法需要更密集的计算。因此,可能区别在于,在内存较少的机器上,toString需要更多的垃圾收集回合,而在处理器较慢的机器上,额外的log计算将更加痛苦。
我还尝试了第三种方法。我写了这个小函数:
static int numlength(int n)
{
if (n == 0) return 1;
int l;
n=Math.abs(n);
for (l=0;n>0;++l)
n/=10;
return l;
}
在我的机器上,它运行在1600到1900毫厘之间——不到toString方法的1/3,log方法的1/10。
如果您的数字范围很广,您可以通过开始除以1000或1,000,000来进一步加快速度,以减少循环的次数。我还没玩过。
没有字符串API,没有utils,没有类型转换,只是纯java迭代->
public static int getNumberOfDigits(int input) {
int numOfDigits = 1;
int base = 1;
while (input >= base * 10) {
base = base * 10;
numOfDigits++;
}
return numOfDigits;
}
如果你愿意,你可以追求更大的价值。
理想情况下,一个整数除以10的倍数将返回位数,只要该整数不为零。这样一个简单的方法可以创建如下所示。
public static int getNumberOfDigits(int number) {
int numberOfDigits = 0;
while(number != 0) {
number /= 10;
numberOfDigits++;
}
return numberOfDigits;
}