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

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

当前回答

下面是JDK开发人员给出的解决方案。JDK 17 (Long类):

/**
 * Returns the string representation size for a given long value.
 *
 * @param x long value
 * @return string size
 *
 * @implNote There are other ways to compute this: e.g. binary search,
 * but values are biased heavily towards zero, and therefore linear search
 * wins. The iteration results are also routinely inlined in the generated
 * code after loop unrolling.
 */
static int stringSize(long x) {
    int d = 1;
    if (x >= 0) {
        d = 0;
        x = -x;
    }
    long p = -10;
    for (int i = 1; i < 19; i++) {
        if (x > p)
            return i + d;
        p = 10 * p;
    }
    return 19 + d;
}

注意,如果需要的话,该方法会考虑减号。

不幸的是,该方法没有公开。

在性能方面,您可以从评论中看到,JDK开发人员与其他选项相比至少考虑了这一点。我猜 分而治之的方法倾向于较小的数字,效果会稍好一些 更好,因为CPU可以比整数更快地进行整数比较 乘法。但这种差异可能小到无法测量。

无论如何,我希望JDK中已经公开了这个方法,这样人们就不会开始使用自己的方法了。

其他回答

那简单的数学呢?除以10,直到0。

public static int getSize(long number) {
        int count = 0;
        while (number > 0) {
            count += 1;
            number = (number / 10);
        }
        return count;
    }

理想情况下,一个整数除以10的倍数将返回位数,只要该整数不为零。这样一个简单的方法可以创建如下所示。

public static int getNumberOfDigits(int number) {
    int numberOfDigits = 0;                
    while(number != 0) {
        number /= 10;
        numberOfDigits++;
    }
    
    return numberOfDigits;
}

我看到有人使用String库,甚至使用Integer类。这没什么问题,但是求位数的算法并不复杂。我在这个例子中使用的是long类型,但它也可以用于int类型。

 private static int getLength(long num) {

    int count = 1;

    while (num >= 10) {
        num = num / 10;
        count++;
    }

    return count;
}

用设计(基于问题)。这是分治法的另一种。我们将首先定义一个枚举(考虑到它仅用于unsigned int)。

public enum IntegerLength {
    One((byte)1,10),
    Two((byte)2,100),
    Three((byte)3,1000),
    Four((byte)4,10000),
    Five((byte)5,100000),
    Six((byte)6,1000000),
    Seven((byte)7,10000000),
    Eight((byte)8,100000000),
    Nine((byte)9,1000000000);

    byte length;
    int value;

    IntegerLength(byte len,int value) {
        this.length = len;
        this.value = value;
    }

    public byte getLenght() {
        return length;
    }

    public int getValue() {
        return value;
    }
}

现在我们将定义一个类,它遍历枚举的值,并比较并返回适当的长度。

public class IntegerLenght {
    public static byte calculateIntLenght(int num) {    
        for(IntegerLength v : IntegerLength.values()) {
            if(num < v.getValue()){
                return v.getLenght();
            }
        }
        return 0;
    }
}

此解决方案的运行时间与分治方法相同。

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

它基于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;
}