jdk源码:Long.toString(long i, int radix)和Long.toUnsignedString(long i, int radix)

  Seves

1. 区别

toString方法将数字转为有符号数对应的字符串,toUnsignedString是将数字转为有符号数对应的字符串。

2. toString(long i, int radix)

public static String toString(long i, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;
        if (radix == 10)
            return toString(i);
        char[] buf = new char[65];
        int charPos = 64;
        boolean negative = (i < 0);

        if (!negative) {
            i = -i;
        }

        while (i <= -radix) {
            buf[charPos--] = Integer.digits[(int)(-(i % radix))];
            i = i / radix;
        }
        buf[charPos] = Integer.digits[(int)(-i)];

        if (negative) {
            buf[--charPos] = '-';
        }

        return new String(buf, charPos, (65 - charPos));
    }
    public static String toString(long i) {
        if (i == Long.MIN_VALUE)
            return "-9223372036854775808";
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        getChars(i, size, buf);
        return new String(buf, true);
    }
  • 当非10进制的时候
boolean negative = (i < 0);
if (!negative) {
            i = -i;
        }

        while (i <= -radix) {
            buf[charPos--] = Integer.digits[(int)(-(i % radix))];
            i = i / radix;
        }
        buf[charPos] = Integer.digits[(int)(-i)];

        if (negative) {
            buf[--charPos] = '-';
        }

这里有个比较巧妙的地方我开始没有想通,就是为什么把数字都统一转为负数来处理呢。首先肯定是统一转为正数或者负数处理,那为什么是负数。答案就是有负数数字负数比负数多一个数字,比如64位系统Long的范围是-9223372036854775808 ~ 9223372036854775807。当遇到Long最大正数9223372036854775807时,可以转为-9223372036854775807,但是当你遇到Long最小负数-9223372036854775808时转为正数就会溢出。所以统一转为负数处理可以多处理一个数。

3. toUnsignedString(long i, int radix)

    public static String toUnsignedString(long i, int radix) {
        if (i >= 0)
            return toString(i, radix);
        else {
            switch (radix) {
            case 2:
                return toBinaryString(i);

            case 4:
                return toUnsignedString0(i, 2);

            case 8:
                return toOctalString(i);

            case 10:
                /*
                 * We can get the effect of an unsigned division by 10
                 * on a long value by first shifting right, yielding a
                 * positive value, and then dividing by 5.  This
                 * allows the last digit and preceding digits to be
                 * isolated more quickly than by an initial conversion
                 * to BigInteger.
                 */
                long quot = (i >>> 1) / 5;
                long rem = i - quot * 10;
                return toString(quot) + rem;

            case 16:
                return toHexString(i);

            case 32:
                return toUnsignedString0(i, 5);

            default:
                return toUnsignedBigInteger(i).toString(radix);
            }
        }
    }

作者 @没有故事的老大爷
一定要专注,这样才会忘记痛苦

28