1、 toString
public static String toString(int i, int radix) {
//Character.MIN_RADIX、MAX_RADIX分别表示进制最大和最小,最小为2进制,最高为36进制
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
/* Use the faster version */
if (radix == 10) {
return toString(i);
}
//创建33位数组,int位32位,还有一位是符号
char buf[] = new char[33];
boolean negative = (i < 0);
int charPos = 32;
//取负
if (!negative) {
i = -i;
}
//将对应位转换为对应进制
while (i <= -radix) {
buf[charPos--] = digits[-(i % radix)];
i = i / radix;
}
buf[charPos] = digits[-i];
//加符号
if (negative) {
buf[--charPos] = '-';
}
return new String(buf, charPos, (33 - charPos));
}
2、 大部分进制转换都会用到的
private static String toUnsignedString0(int val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
//val非零位置个数
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
//mag为大于等于0,小于等于32的数,(shift - 1)的作用是当位数不能被radix整除时做的填充作用,比如mag = 17 shift=4,如果不加(shift-1)的话就是4少了,所以需要加。
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);
}
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
int charPos = len;
//把shift转换成对应的真正的进制radix
int radix = 1 << shift;
int mask = radix - 1;
do {
//val&mask 相当于 val%(mask+1)
//总的来说也就是找到对应位对应的字母或数字
buf[offset + --charPos] = Integer.digits[val & mask];
val >>>= shift;
} while (val != 0 && charPos > 0);
return charPos;
//这个方法非常精妙,出现1之前,出现了多少个0,先右移16位如果为0则前16位全部为0,然后左移16位,在这剩下的16位基础上再用同样的方法看剩下几个0,
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;
}
//返回从最右端开始直到第一个1共有几个0
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
}
3、getChar
static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
i = -i;
}
// Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
//对q/100求余
//效率方面乘法优于除法,位运算优于乘法
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
//对i/10求余,52429 2^19也是为了精度
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}
4、 compareUnsigned为什么就加个MIN_VALUE就是unsign了
public static int compareUnsigned(int x, int y) {
return compare(x + MIN_VALUE, y + MIN_VALUE);
}
5、 highestOneBit只剩下最高位1的数,比如输入20(10100)会输出16(10000)
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
public static int lowestOneBit(int i) {
// HD, Section 2-1
return i & -i;
}
6、bitcount,计算共有多少位的 1,可以参考这篇博文:链接
public static int bitCount(int i) {
// HD, Figure 5-2
//0x5 = 0101
//0x3 = 0011
//0x0f = 00001111
//0x3f = 00111111
//以i=11为列子:1011
//则用两位统计是0110:1+2 = 3
i = i - ((i >>> 1) & 0x55555555);
//则用四位统计是0011: 3,其它都是一样的
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
//最多32个1,所以要2^5,即100000,用0x3f取数
return i & 0x3f;
}
这块还是比较冉,留以后再看吧
7、 >>> -1表示右移1的补码(只去后6位)
8、 日狗的位运算,剩下几个留着吧
public static int rotateLeft(int i, int distance) {
return (i << distance) | (i >>> -distance);
}
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
public static int signum(int i) {
// HD, Section 2-7
return (i >> 31) | (-i >>> 31);
}
public static int reverseBytes(int i) {
return ((i >>> 24) ) |
((i >> 8) & 0xFF00) |
((i << 8) & 0xFF0000) |
((i << 24));
}