Integer.toBinaryString()方法是将int类型的数字转化为二进制然后以字符串形式输出。
疑问1:负数的输出为什么有那么多1?
因为这里是将Integer是int的包装类,在内存中也是占4个字节,32位,所以是负数一共有32位。
解释一下i<<=2:
i左移两位然后赋给i,此时i=-4,与+=/-=意思相同,只不过这里是位运算。
Integer.valueof():
将二进制转为十进制。
2)“>>>”运算符所作的是无符号的位移处理。比较神奇的是,无符号右移后少了一位,具体对比如下:
那右移两位呢?发现又少了一位。但是为什么我就不是很清楚了。欢迎评论。
扫描二维码关注公众号,回复:
1841778 查看本文章
右移31位呢???变成1了。
回顾 十进制-》二进制
正数:4-》0000 0100
负数:-4-》1000 0100(原码)-》1111 1011(取反)-》1111 1100(末位加一)
在计算机中,负数以其正值的补码形式表达,方法符号位置为1,然后取反加一。
<< 1 最右边都是用0补位,基本等于乘以 2,乘法会发生上溢的。
>> 1 最左边会保持原符号位的值,基本等于除以 2.
>>> 1 最左边会用0补位。
进源码:
其中:
1) j -= i >> 31;
等价与
int x=j-i;
j=x>>31;
说明-=的优先级大于位运算。
2)补码就是负数在计算机中的二进制表示方法。那么,11111011表示8位的-5,如果要表示16位的-5 ,在左边添上8个1即可。
java.lang源码参考(十进制转二进制):
public static void main(String[] args) {
int i=-1;
String j=toBinaryString(i);
System.out.println(j);
}
public static String toBinaryString(int i)
{
return toUnsignedString0(i, 1);
}
public static int numberOfLeadingZeros(int i)
{
if(i == 0)
return 32;
int j = 1;
if(i >>> 16 == 0)
{
j += 16;
i <<= 16;
}
if(i >>> 24 == 0)
{
j += 8;
i <<= 8;
}
if(i >>> 28 == 0)
{
j += 4;
i <<= 4;
}
if(i >>> 30 == 0)
{
j += 2;
i <<= 2;
}
int x=j-i;
j=x>>31;
// j -= i >>> 31;
return j;
}
private static String toUnsignedString0(int i, int j) {
int k = 32 - numberOfLeadingZeros(i);
int l = Math.max((k + (j - 1)) / j, 1);
char ac[] = new char[l];
formatUnsignedInt(i, j, ac, 0, l);
char[] s = Arrays.copyOf(ac, ac.length);
return new String(s);
}
static int formatUnsignedInt(int i, int j, char ac[], int k, int l) {
int i1 = l;
int j1 = 1 << j;
int k1 = j1 - 1;
do {
ac[k + --i1] = digits[i & k1];
i >>>= j;
} while (i != 0 && i1 > 0);
return i1;
}
static final 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'
};