编程语言
首页 > 编程语言> > 探索Integer.toBinaryString源码

探索Integer.toBinaryString源码

作者:互联网

不解驱动着你

一般情况下我是不会主动去看源码的,除非是写专门的主题或者是遇到不懂的难题。果然了,于是带着好奇心尝试理解下源码,一会我先抛出问题,要是有同学一下子就明白了那就可以不用往下看了!还有一个前提就是最好对原码、补码、反码有所了解,因为计算机操作的数据就是以二进制的形式存在的,准确的说是用补码的形式来计算的!

    public class URShift {
        public static void main(String[] args) {
            int i = -1;
            System.out.println("①:" + Integer.toBinaryString(i));

            i >>>= 10;
            System.out.println("②:" + Integer.toBinaryString(i));

            long l = -1;
            System.out.println("③:" + Long.toBinaryString(l));

            l >>>= 10;
            System.out.println("④:" + Long.toBinaryString(l));

            short s = -1;
            System.out.println("⑤:" + Integer.toBinaryString(s));

            s >>>= 10;
            System.out.println("⑥:" + Integer.toBinaryString(s));

            byte b = -1;
            System.out.println("⑦:" + Integer.toBinaryString(b));

            b >>>= 10;
            System.out.println("⑧:" + Integer.toBinaryString(b));
        }
    }
①:11111111111111111111111111111111
②:1111111111111111111111
③:1111111111111111111111111111111111111111111111111111111111111111
④:111111111111111111111111111111111111111111111111111111
⑤:11111111111111111111111111111111
⑥:11111111111111111111111111111111
⑦:11111111111111111111111111111111
⑧:11111111111111111111111111111111

源码

Integer.toBinaryString内部实现的方法主要有两个:numberOfLeadingZeros formatUnsignedInt,剩下的就无关紧要了,所以接下来的内容主要围绕着两个方法来讲。

    public static int numberOfLeadingZeros(int i) {
        if (i == 0)
            return 32;
        int n = 1;
        if (i >>> 16 == 0) { n += 16; i <<= 16; }
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }
        n -= i >>> 31;
        return n;
    }

开始之前在复习下计算机的原码、补码、反码的相关计算,举个简单的例子。

数值 原码 反码 补码
1 0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0001
-1 1000 0000 0000 0000 0000 0000 0000 0001 1111 1111 1111 1111 1111 1111 1111 1110 1111 1111 1111 1111 1111 1111 1111 1111

为了方便理解,我们采用假设的方式来引导读者。针对numberOfLeadingZeros方法假设入参i = 1,以下分多个步骤来分析该方法,在分析方法之前先跟读者说下该方法的主要作用是:获取该二进制从左侧开始数连续0的个数,有了这个个数就能构建数组的大小去存储有效的数据,二进制中前置位为0的话是不会存储的。

数值 计算前 移位 计算后
1 0000 0000 0000 0000 0000 0000 0000 0001 左移16 0000 0000 0000 0000 0000 0000 0000 0000

很显然,结果是等于0,故此时n = 17,而i又做了计算,如下:

数值 计算前 移位 计算后
1 0000 0000 0000 0000 0000 0000 0000 0001 右移16 0000 0000 0000 0001 0000 0000 0000 0000
数值 计算前 移位 计算后
1 0000 0000 0000 0001 0000 0000 0000 0001 右移24 0000 0000 0000 0000 0000 0000 0000 0000

结果等于0,此时n = 25,而i又做了计算,如下:

数值 计算前 移位 计算后
1 0000 0000 0000 0001 0000 0000 0000 0001 右移24 0000 0001 0000 0000 0000 0000 0000 0000

相当于准备要计算最后的8位了,那么就看下一个判断语句了。

数值 结果值
1 0100 0000 0000 0000 0000 0000 0000 0000

接下来讨论另外一个方法formatUnsignedInt,紧接着上面假设后得出的结果,所以mag = 1,表示该数值的有效位是1位,故将会构建长度为1的数组,对于任意数据,最小的长度就是1,而对于最大的长度就要看具体的数值了。好了,formatUnsignedInt方法中入参为val = 1, shift = 1, buf = new char[1], offset = 0, len = 1。在分析之前先说下该方法的主要作用,其实也没啥可说的,就是将数组解析成二进制后并放入到数组中

结束语

源码在适当的情况下还是需要去看的,笔者正在一步一步往这里靠近,努力加强自己的硬实力!加油自己,加油每一个人!

标签:0000,0001,16,1111,源码,toBinaryString,计算,Integer
来源: https://www.cnblogs.com/zlia/p/14157349.html