toUnsignedString详解

     /**
* All possible chars for representing a number as a String
*/
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'
}; /**
* Convert the integer to an unsigned number.
*/
private static String toUnsignedString(int i, int shift) {
char[] buf = new char[32];//当shift为1二进制时,char数组大小32刚好,而当shift为3,4时,数组大小有余
int charPos = 32;//当数组有余时,便于取char数组中的数据
int radix = 1 << shift;//算数左移,radix中间变量用于计算mask
int mask = radix - 1;//mask掩码用于获取i的shift位低位,mask二进制数每一位都是1
do {
buf[--charPos] = digits[i & mask];//取出i二进制数低位shift位,将对应的字符存入buf
//新建数组大小时[]填32,但是在数组赋值时[]填0~31
i >>>= shift;//逻辑右移,剔除已取出的shfit位低位
} while (i != 0); return new String(buf, charPos, (32 - charPos));
}

1. 掩码mask的计算。shift参数用于区分不同进制,比如二进制的shift=1,mask=1;八进制的shift=3,mask=7;十六进制的shift=4,mask=15。

2. 右移使用的是>>>而不是>>。位运算中的右移分为算术右移(>>)和逻辑右移(>>>)。在进行算术右移时,最高位补符号位;而在进行逻辑右移时,最高位补0。如果这里使用的算术右移,那么对于像-1这样的负数,不论进行多少次右移操作都不可能变成0,所以会造成死循环。

3. 使用的是do-while而不是while。这是一个极其重要的细节,如果使用的是while,那么对于i=0的场景则会返回空字符串。

4. 算术左移(<<)、右移(>>)主要用来进行有符号数的倍增、减半;
    逻辑左移(<<<)、右移(>>>)主要用来进行无符号数的倍增、减半。(左移都是低位补0,算数右移高位补符号位,逻辑右移高位补0)

5.

二进制:

public static String toBinaryString(int i) {
 return toUnsignedString(i, 1);
    }

八进制:

public static String toOctalString(int i) {
 return toUnsignedString(i, 3);
    }

十六进制:

public static String toHexString(int i) {
 return toUnsignedString(i, 4);
    }

补充:每个IP地址都由网络号和主机号两部分组成,通过子网掩码(subnet mask)区分网络号和主机号(子网掩码:255.0.0.0;255二进制数1111)

参考原文:http://www.cnblogs.com/jtree/p/4162321.html

上一篇:Random.nextint() 和Math.random()的区别


下一篇:Aria2GUI 导出下载 刷新界面,任务消失