JDK源码之拓展——如何求一个整数的位数

Posted 二木成林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK源码之拓展——如何求一个整数的位数相关的知识,希望对你有一定的参考价值。

本题是引申自:JDK源码之Integer类——stringSize()方法

如何求一个整数的位数

第一种:使用sizeTable数组

public class Test {
    final static int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999,
            99999999, 999999999, Integer.MAX_VALUE};

    /**
     * 统计传入整数的数字位数,比如123是3位数字,4568是4位数字
     *
     * @param x 正整数,但事实在该方法内并没有判断该数是否是一个正整数
     * @return 返回x的位数
     */
    static int stringSize(int x) {
        // i是临时变量,用来统计一个数的位数
        for (int i = 0; ; i++)
            // 判断传入的参数x是否小于等于sizeTable[i],则返回x的位数
            if (x <= sizeTable[i])
                return i + 1;// 因为索引是从0开始的,所以要加1
    }

    public static void main(String[] args) {
        // 输出正数的位数
        System.out.println(stringSize(123));// 3
        System.out.println(stringSize(45678));// 5

        // 输出负数的位数,注意,负数的结果都为1
        System.out.println(stringSize(-321));// 1
        System.out.println(stringSize(-789456));// 1
    }
}

注意事项:

  • 这种方法来源于JDK1.8的Integer类中的源码。
  • 能够判断正整数的数字位数,但最大的范围是Integer.MAX_VALUE,即2147483647。
  • 不能够判断负整数的数字位数,无论是几位的负数,都只会输出1,因为都小于9。

第二种:

public class Test {
    // 出于兼容性原因,请留在此处,请参阅JDK-8143900。
    // 下面这个数组其实没有被用到过,但JDK1.9却留下了,因为JDK1.8及之前的版本会用到这个数组
    static final int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999,
            99999999, 999999999, Integer.MAX_VALUE};
    
    /**
     * 返回给定int值的字符串表示大小,即一个数字的位数,如数字123的位数是3位,数字4567的位数是4位
     *
     * @param x 给定的整数
     * @return 返回字符串大小,即位数
     */
    static int stringSize(int x) {
        // 局部变量,计数器
        int d = 1;// 如果是负数则d=1,如果是正数则d=0,为什么呢?因为负数会把符号位计算在内,如-123执行的结果是4
        // 判断给定的整数x是否是一个正数
        if (x >= 0) {
            // 并且将d重置为0
            d = 0;
            // 如果x是一个正数,则转换成一个负数
            x = -x;
        }
 
        // 局部变量,用于循环
        int p = -10;
        for (int i = 1; i < 10; i++) {// 为什么是i<10,因为int数据类型的范围最大为2147483647,即10位数字
            if (x > p)// 用于确定数字的位数
                return i + d;
            p = 10 * p;// 循环
        }
        return 10 + d;
    }
 
    public static void main(String[] args) {
        // 输出数字123的位数
        System.out.println(stringSize(2147483647));// 10
        // 输出数字123456的位数
        System.out.println(stringSize(123456));// 6
 
        // 但注意,传入的参数如果是负数,那么也会返回负数的位数,但是会包括符号位在内,例如-123返回4
        System.out.println(stringSize(-123));// 4
        System.out.println(stringSize(-654321));// 7
    }
}

注意事项:

  • 这种方法来源于JDK1.9的Integer类中的源码。
  • 能够判断正整数的数字位数,但最大的范围是Integer.MAX_VALUE,即2147483647。
  • 能够判断负数的位数,但包括符号位在内,如-123的位数是4。

第三种:字符串的长度

public class Test {

    /**
     * 返回给定int值的字符串表示大小,即一个数字的位数,如数字123的位数是3位,数字4567的位数是4位
     *
     * @param x 给定的整数
     * @return 返回字符串大小,即位数
     */
    static int stringSize(int x) {
        return String.valueOf(x).length();
    }

    public static void main(String[] args) {
        // 输出数字123的位数
        System.out.println(stringSize(2147483647));// 10
        // 输出数字123456的位数
        System.out.println(stringSize(123456));// 6

        // 但注意,传入的参数如果是负数,那么也会返回负数的位数,但是会包括符号位在内,例如-123返回4
        System.out.println(stringSize(-123));// 4
        System.out.println(stringSize(-654321));// 7
    }
}

注意事项:

  • 思路就是将数字转换成字符串,然后求字符串的长度。
  • 能够判断正整数的数字位数,但最大的范围是Integer.MAX_VALUE,即2147483647。
  • 能够判断负数的位数,但包括符号位在内,如-123的位数是4。

第四种:取余判断

public class Test {

    /**
     * 返回给定int值的字符串表示大小,即一个数字的位数,如数字123的位数是3位,数字4567的位数是4位
     *
     * @param x 给定的整数
     * @return 返回字符串大小,即位数
     */
    static int stringSize(int x) {
        // 计数器,记录数字的位数
        int count = 0;
        while (x > 0) {
            count++;
            x /= 10;
        }
        return count;
    }

    public static void main(String[] args) {
        // 输出数字123的位数
        System.out.println(stringSize(2147483647));// 10
        // 输出数字123456的位数
        System.out.println(stringSize(123456));// 6

        // 但注意,传入的参数如果是负数,那么会返回0
        System.out.println(stringSize(-123));// 0
        System.out.println(stringSize(-654321));// 0
    }
}

注意事项:

  • 思路就是循环对正数x进行取余,然后计算数字的位数。
  • 能够判断正整数的数字位数,但最大的范围是Integer.MAX_VALUE,即2147483647。
  • 不能够判断负数的位数,会返回0。

第五种:数学公式

public class Test {

    /**
     * 返回给定int值的字符串表示大小,即一个数字的位数,如数字123的位数是3位,数字4567的位数是4位
     *
     * @param x 给定的整数
     * @return 返回字符串大小,即位数
     */
    static int stringSize(int x) {
        return (int) Math.log10(x) + 1;
    }

    public static void main(String[] args) {
        // 输出数字123的位数
        System.out.println(stringSize(2147483647));// 10
        // 输出数字123456的位数
        System.out.println(stringSize(123456));// 6

        // 但注意,传入的参数如果是负数,那么会返回1
        System.out.println(stringSize(-123));// 1
        System.out.println(stringSize(-654321));// 1
    }
}

注意事项:

  • 思路就是利用数学公式。
  • 能够判断正整数的数字位数,但最大的范围是Integer.MAX_VALUE,即2147483647。
  • 不能够判断负数的位数,会返回1。

以上是关于JDK源码之拓展——如何求一个整数的位数的主要内容,如果未能解决你的问题,请参考以下文章

0009JDK源码分析之拓展字符集

JDK源码之Integer类—bitCount()方法

c语言,求任意一个整数各位数字之积

JDK源码之Integer类——rotateRight()方法

JDK源码之Integer类—toString()方法

0007JDK源码分析之揭秘整数常量池实现机制