有没有比这个方法更简洁的方法来获取整数的位数?

int numDigits = String.valueOf(1000).length();

当前回答

我能试试吗?;)

基于德克的解决方案

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

这取决于你对“整洁”的定义。我认为下面的代码相当简洁,运行速度也很快。

它基于Marian的回答,扩展到所有long值,并使用?:运营商。

private static long[] DIGITS = { 1l,
                                 10l,
                                 100l,
                                 1000l,
                                 10000l,
                                 100000l,
                                 1000000l,
                                 10000000l,
                                 100000000l,
                                 1000000000l,
                                 10000000000l,
                                 100000000000l,
                                 1000000000000l,
                                 10000000000000l,
                                 100000000000000l,
                                 1000000000000000l,
                                 10000000000000000l,
                                 100000000000000000l,
                                 1000000000000000000l };

public static int numberOfDigits(final long n)
{
    return n == Long.MIN_VALUE ? 19 : n < 0l ? numberOfDigits(-n) :
            n < DIGITS[8] ? // 1-8
              n < DIGITS[4] ? // 1-4
                n < DIGITS[2] ? // 1-2
                  n < DIGITS[1] ? 1 : 2 : // 1-2
                        n < DIGITS[3] ? 3 : 4 : // 3-4
                      n < DIGITS[6] ? // 5-8
                        n < DIGITS[5] ? 5 : 6 : // 5-6
                      n < DIGITS[7] ? 7 : 8 : // 7-8
            n < DIGITS[16] ? // 9-16
              n < DIGITS[12] ? // 9-12
                n < DIGITS[10] ? // 9-10
                  n < DIGITS[9] ? 9 : 10 : // 9-10
                        n < DIGITS[11] ? 11 : 12 : // 11-12
                      n < DIGITS[14] ? // 13-16
                        n < DIGITS[13] ? 13 : 14 : // 13-14
                      n < DIGITS[15] ? 15 : 16 : // 15-16
            n < DIGITS[17] ? 17 :  // 17-19
            n < DIGITS[18] ? 18 :
            19;
}

由于以10为基数的整数的位数只是1 + truncate(log10(number)),您可以这样做:

public class Test {

    public static void main(String[] args) {

        final int number = 1234;
        final int digits = 1 + (int)Math.floor(Math.log10(number));

        System.out.println(digits);
    }
}

被编辑是因为我的最后一次编辑修复了代码示例,但没有修复描述。

出于好奇,我试着对其进行基准测试……

import org.junit.Test;
import static org.junit.Assert.*;


public class TestStack1306727 {

    @Test
    public void bench(){
        int number=1000;
        int a= String.valueOf(number).length();
        int b= 1 + (int)Math.floor(Math.log10(number));

        assertEquals(a,b);
        int i=0;
        int s=0;
        long startTime = System.currentTimeMillis();
        for(i=0, s=0; i< 100000000; i++){
            a= String.valueOf(number).length();
            s+=a;
        }
        long stopTime = System.currentTimeMillis();
        long runTime = stopTime - startTime;
        System.out.println("Run time 1: " + runTime);
        System.out.println("s: "+s);
        startTime = System.currentTimeMillis();
        for(i=0,s=0; i< 100000000; i++){
            b= number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
            s+=b;
        }
        stopTime = System.currentTimeMillis();
        runTime = stopTime - startTime;
        System.out.println("Run time 2: " + runTime);
        System.out.println("s: "+s);
        assertEquals(a,b);


    }
}

结果如下:

Run time 1: 6765
s: 400000000
Run time 2: 6000
s: 400000000

现在我想知道我的基准测试是否真的意味着什么,但我确实在基准测试本身的多次运行中得到了一致的结果(一毫秒内的变化)……:)看起来这是无用的尝试和优化…


编辑:根据ptomli的注释,我在上面的代码中用' I '替换'number',并在5次运行的bench中得到以下结果:

Run time 1: 11500
s: 788888890
Run time 2: 8547
s: 788888890

Run time 1: 11485
s: 788888890
Run time 2: 8547
s: 788888890

Run time 1: 11469
s: 788888890
Run time 2: 8547
s: 788888890

Run time 1: 11500
s: 788888890
Run time 2: 8547
s: 788888890

Run time 1: 11484
s: 788888890
Run time 2: 8547
s: 788888890

我能试试吗?;)

基于德克的解决方案

final int digits = number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));