Java BigInteger的toString递归算法中n值计算逻辑的疑问
关于Java BigInteger递归toString方法中n值计算的疑惑
Java的BigInteger递归实现toString的核心方法如下:
toString(BigInteger u, StringBuilder sb, int radix, int digits)
该方法的核心思路是将目标数字u按radix、radix²、radix⁴、radix⁸(本质是radix^(2ⁿ))的层级划分,通过递归调用拼接结果。
原代码中用于计算关键参数n的逻辑是:
int b = u.bitLength(); int n = (int) Math.round(Math.log(b * LOG_TWO / logCache[radix]) / LOG_TWO - 1.0);
得到n后,会通过以下代码完成数字划分与递归拼接:
BigInteger v = getRadixConversionCache(radix, n); BigInteger[] results; results = u.divideAndRemainder(v); int expectedDigits = 1 << n; // 递归构建数字的前后两半 toString(results[0], sb, radix, digits - expectedDigits); toString(results[1], sb, radix, expectedDigits);
我对上述n的计算逻辑存在疑问:原代码的计算方式似乎不合理,我认为应该改用Math.floor并去掉-1.0,即:
Math.floor(Math.log(b * LOG_TWO / logCache[radix]) / LOG_TWO)
这样才能更准确找到合适的radix^(2ⁿ)进行数字划分。
我以radix范围2到1024(即2¹到2¹⁰)做了测试,测试的radix列表为:
[2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
使用原代码计算得到的n值结果为:
[-3, -2, -1, -1, 0, 0, 0, 0, 0, 1]
该结果明显存在异常;而使用我提出的计算方式得到的n值结果为:
[-2, -1, -1, 0, 0, 0, 1, 1, 1, 1]
这个结果更符合逻辑预期。
内容的提问来源于stack exchange,提问作者femto
相关产品推荐
相关产品推荐

