解析JDK将数字转化为二进制字符串

测试代码

public static void main(String[] args) {
    int num = 65481;
    String binString = Integer.toBinaryString(num);
    System.out.println(num + "的二进制为:" + binString);
}

输出结果

65481的二进制为:1111111111001001


JDK源码:Integer.java

public static String toBinaryString(int i) {
    return toUnsignedString0(i, 1);
}
/**
 * Convert the integer to an unsigned number.
 */
private static String toUnsignedString0(int val, int shift) {
    // assert shift > 0 && shift <=5 : "Illegal shift value";
    int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
    int chars = Math.max(((mag + (shift - 1)) / shift), 1);
    char[] buf = new char[chars];

    formatUnsignedInt(val, shift, buf, 0, chars);

    // Use special constructor which takes over "buf".
    return new String(buf, true);
}
public static int numberOfLeadingZeros(int i) {
    // HD, Figure 5-6
    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;
}
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
    int charPos = len;
    int radix = 1 << shift;
    int mask = radix - 1;
    do {
        buf[offset + --charPos] = Integer.digits[val & mask];
        val >>>= shift;
    } while (val != 0 && charPos > 0);

    return charPos;
}
final static char[] digits = {
    '0' , '1' , '2' , '3' , '4' , '5' ,
    '6' , '7' , '8' , '9' , 'a' , 'b' ,
    'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
    'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
    'o' , 'p' , 'q' , 'r' , 's' , 't' ,
    'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};

代码解释

先看numberOfLeadingZeros(int)方法:这个方法的意义是确定它的二进制前面有多少个0。我们传进来的数是65481.先来看看它的原码。

0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 1 1 1 1 1 1 1 1 | 1 1 0 0 1 0 0 1

先将它无符号右移16位,判断是否为0:

0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0

由此推断,64581的高16为全都是0.于是将它左移16位,继续推低16位:

1 1 1 1 1 1 1 1 | 1 1 0 0 1 0 0 1 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0

将它无符号右移24位:

0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 1 1 1 1 1 1 1 1

不为0;继续无符号右移28位:

0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 1 1 1 1

不为0;继续右移30位:

0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 1 1

不为0;看最后1位是否为0.因为n默认最后为0,如果最后不是0,就要减去这种情况:

0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1

最后得到 n = 16;也就是说,65481的二进制只有16位有效位。返回到函数中,创建一个长度为16的char数组。跳转到formatUnsignedInt函数中。每一次都将65481和1进行二进制与并且将其右移一位,以达到遍历它的低16位的目的。然后依次倒序填充到char数组中,将其以字符串的形式输出。

猜你喜欢

转载自blog.csdn.net/Yujiumin/article/details/81018569