Java's BigInteger's toString use recursive algorithm,
toString(BigInteger u, StringBuilder sb,
int radix, int digits)
it divides u into ranges of radix,radix^2,radix^4,radix^8(basically radix^2^n),
int b = u.bitLength();
int n = (int) Math.round(Math.log(b * LOG_TWO / logCache[radix]) /
LOG_TWO - 1.0);
then decides u falls into which range and use divideAndRemainder to concatnate the result (it's a recursive algorithm)
BigInteger v = getRadixConversionCache(radix, n);
BigInteger[] results;
results = u.divideAndRemainder(v);
int expectedDigits = 1 << n;
// Now recursively build the two halves of each number.
toString(results[0], sb, radix, digits - expectedDigits);
toString(results[1], sb, radix, expectedDigits);
the confusing part to me is, why it uses
Math.round(Math.log(b * LOG_TWO / logCache[radix]) /
LOG_TWO - 1.0)
I think it should use floor, and without - 1.0
Math.floor(Math.log(b * LOG_TWO / logCache[radix]) /
LOG_TWO)
to find the proper radix^2^n to divide, also I take from 2 to 1024 for a test(2^1 to 2^10)
[2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
if using
Math.round(Math.log(b * LOG_TWO / logCache[radix]) /
LOG_TWO - 1.0)
then it becomes
[-3, -2, -1, -1, 0, 0, 0, 0, 0, 1]
which seems wrong, but using
Math.floor(Math.log(b * LOG_TWO / logCache[radix]) /
LOG_TWO)
the result is
[-2, -1, -1, 0, 0, 0, 1, 1, 1, 1]
which seemed correct