/** * 该方法主要做的是将某个long型数值放到char数组里面。如把357按顺序放到char数组 */ staticvoidgetChars(long i, int index, char[] buf){ long q; int r; int charPos = index; char sign = 0;
if (i < 0) { sign = '-'; i = -i; }
// 将long拆成高位4个字节和低位4个字节处理分开处理,while (i >= Integer.MAX_VALUE)部分就是处理高位的4个字节 while (i > Integer.MAX_VALUE) { q = i / 100; // really: r = i - (q * 100); // ((q << 6) + (q << 5) + (q << 2))其实等于q*100,用来获取十位和个位 r = (int)(i - ((q << 6) + (q << 5) + (q << 2))); i = q; // 每次处理2位数 buf[--charPos] = Integer.DigitOnes[r]; buf[--charPos] = Integer.DigitTens[r]; }
// 处理低4个字节,继续将4个字节分为高位2个字节和低位2个字节 int q2; int i2 = (int)i; // while (i >= 65536)部分就是处理高位的两个字节,每次处理2位数,处理逻辑与高位4个字节的处理逻辑一样 while (i2 >= 65536) { q2 = i2 / 100; // really: r = i2 - (q * 100); r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); i2 = q2; buf[--charPos] = Integer.DigitOnes[r]; buf[--charPos] = Integer.DigitTens[r]; }
// Handle radix specifier, if present if (nm.startsWith("0x", index) || nm.startsWith("0X", index)) { index += 2; radix = 16; } elseif (nm.startsWith("#", index)) { index ++; radix = 16; } elseif (nm.startsWith("0", index) && nm.length() > 1 + index) { index ++; radix = 8; }
if (nm.startsWith("-", index) || nm.startsWith("+", index)) thrownew NumberFormatException("Sign character in wrong position");
try { result = Long.valueOf(nm.substring(index), radix); result = negative ? Long.valueOf(-result.longValue()) : result; } catch (NumberFormatException e) { // If number is Long.MIN_VALUE, we'll end up here. The next line // handles this case, and causes any genuine format error to be // rethrown. String constant = negative ? ("-" + nm.substring(index)) : nm.substring(index); result = Long.valueOf(constant, radix); } return result; }
/** * 该方法返回i的二进制中最高位的1,其他全为0的值 * 比如i=10时,二进制即为1010,最高位的1,其他为0,则是1000 * 如果i=0,则返回0.如果i为负数则固定返回-2147483648,因为负数的最高位一定是1,即有1000,0000,0000,0000,0000,0000,0000,0000 * 这一堆移位操作是什么意思: 将i右移一位再或操作,则最高位1的右边也为1了,接着再右移两位并或操作,则右边1+2=3位都为1了,接着1+2+4=7位都为1,直到1+2+4+8+16+32=63都为1,最后用i - (i >>> 1)自然得到最终结果 */ publicstaticlonghighestOneBit(long i){ // HD, Figure 3-1 i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); i |= (i >> 32); return i - (i >>> 1); }
/** * 该方法返回i的二进制从头开始有多少个0 * i为0的话则有64个0 * 这里处理其实是体现了二分查找思想的,先看高32位是否为0,是的话则至少有32个0,否则左移16位继续往下判断,接着右移24位看是不是为0,是的话则至少有16+8=24个0,以此类推直到最后得到结果 */ publicstaticintnumberOfLeadingZeros(long i){ // HD, Figure 5-6 if (i == 0) return64; int n = 1; int x = (int)(i >>> 32); if (x == 0) { n += 32; x = (int)i; } if (x >>> 16 == 0) { n += 16; x <<= 16; } if (x >>> 24 == 0) { n += 8; x <<= 8; } if (x >>> 28 == 0) { n += 4; x <<= 4; } if (x >>> 30 == 0) { n += 2; x <<= 2; } n -= x >>> 31; return n; } // 与前面的numberOfLeadingZeros方法对应,该方法返回i的二进制从尾开始有多少个0.它的思想和前面的类似,也是基于二分查找思想 publicstaticintnumberOfTrailingZeros(long i){ // HD, Figure 5-14 int x, y; if (i == 0) return64; int n = 63; y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32); y = x <<16; if (y != 0) { n = n -16; x = y; } y = x << 8; if (y != 0) { n = n - 8; x = y; } y = x << 4; if (y != 0) { n = n - 4; x = y; } y = x << 2; if (y != 0) { n = n - 2; x = y; } return n - ((x << 1) >>> 31); }
/** * 该方法主要用于计算二进制数中1的个数,都是移位和加减操作 * 0x5555555555555555L等于0101010101010101010101010101010101010101010101010101010101010101 * 0x3333333333333333L等于0011001100110011001100110011001100110011001100110011001100110011 * 0x0f0f0f0f0f0f0f0fL等于0000111100001111000011110000111100001111000011110000111100001111 * 它的核心思想就是先每两位一组统计看有多少个1 * 比如10011111则每两位有1、1、2、2个1,记为01011010,然后再算每四位一组看有多少个1,而01011010则每四位有2、4个1,记为00100100,接着每8位一组就为00000110,接着16位,32位,64位,最终在与0x7f进行与运算,得到的数即为1的个数 */ publicstaticintbitCount(long i){ // HD, Figure 5-14 i = i - ((i >>> 1) & 0x5555555555555555L); i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L); i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL; i = i + (i >>> 8); i = i + (i >>> 16); i = i + (i >>> 32); return (int)i & 0x7f; }
/** * 返回通过将指定的值的二进制补码表示形式向左旋转指定位数而获得的值 */ publicstaticlongrotateLeft(long i, int distance){ return (i << distance) | (i >>> -distance); }
/** * 返回通过将指定的值的二进制补码表示形式向右旋转指定位数而获得的值 */ publicstaticlongrotateRight(long i, int distance){ return (i >>> distance) | (i << -distance); }
/** * 该方法即是将i进行反转,反转就是第1位与第64位对调,第二位与第63位对调,以此类推 * 它的核心思想是先将相邻两位进行对换,比如10100111对换01011011,接着再将相邻四位进行对换,对换后为10101101,接着将相邻八位进行对换,最后把64位中中间的32位对换,然后最高16位再和最低16位对换 */ publicstaticlongreverse(long i){ // HD, Figure 7-1 i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L; i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L; i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL; i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL; i = (i << 48) | ((i & 0xffff0000L) << 16) | ((i >>> 16) & 0xffff0000L) | (i >>> 48); return i; }