计算位数和字数 BigInteger

Calculating number of bits and number of words BigInteger

在将 String 转换为 BigInteger 时,Java 在内部计算位数,然后计算字数(我认为每个字是一组 9 个整数)从第 325 行到第 327 行可以看到 here 的 BigInteger。然后使用 numWords 创建一个可以容纳 BigInteger.

的数组

我不明白第 325 行计算 numBits 的逻辑,然后是第 326 行计算 numWords 的逻辑。

逻辑上我认为对于字符串“123456789”,numWords 应该是 1 而对于“12345678912”,numWords 应该是 2,但情况并非总是如此。例如对于“12345678912345678912”,numWords 应该是 3,但结果是 2.

谁能解释一下第 325 行和第 326 行中使用的逻辑?

Words 不是指您所知道的单词 - 它是指作为记忆块的单词。

https://en.wikipedia.org/wiki/Word_(computer_architecture)

要将numDigits的十进制数表示为二进制数,需要

numDigits * Math.log(10) / Math.log(2)

位。

int numBits = (int)(((numDigits * bitsPerDigit[radix]) >>> 10) + 1);

在上面的计算中bitsPerDigit[10]3402

Math.log(10) / Math.log(2) * Math.pow(2, 10) = 3401.6543691646593

在 Java 中,BigIntegers 不存储为字符串或字节,每个字节都有一个数字。它们存储为 32 位整数数组,它们一起构成所谓的 BigInteger 大小。不能有前导零整数 (*),因此 BigInteger 尽可能紧凑地存储。

提到的"words"就是这些32位整数。它们不是 9 位数字的组,它们被完整使用,因此每一位都很重要。

所以你只需要知道存储了多少个32位整数,也就是内部数组的长度乘以32。但是最上面的整数仍然可以有前导零,所以你必须得到前导零的个数那个最高整数,并从获得的产品中减去它们,在伪代码中:

numBits = internalArray.length * 32 - numberOfLeadingZeroBits(internalArray[0]);

请注意,内部数组的最高整数存储在最低地址(我不知道为什么会这样),因此最高整数位于数组的索引 0 处。


(*) 实际上,上面的内容有点复杂,因为顶部项可能存储在距数组开头的偏移处(可能是为了使某些计算更容易),但要理解其机制,你可以假装没有多余的整数。