在 Java 中编写自定义 BigInt 时如何使用大基更有效

How using large base is more efficient when writing custom BigInt in Java

THIS 很可能是 SO 上最长的答案。我试图理解自定义实现,但一开始就卡住了 为什么作者使用 10^9 作为基础而不是 10?用自己的话来说:

As you think the decimal conversion is most complicated part, let's stay in a decimal based mode. For efficiency, we'll store not real decimal digits, but work in base 1 000 000 000 = 10^9 < 2^30. This fits in a Java int (up to 2^31 or 2^32), and the product of two such digits fits nicely in a Java long.

其次,我无法理解这一步:

int decLen = decimal.length(); int bigLen = (decLen-1) /
BASE_DECIMAL_DIGITS + 1;

This strange formula is a Java int way of writing bigLen = ceil(decLen/BASE_DECIMAL_DIGITS). (I hope it is correct, we'll later test it.)

使用我们认为是自然基础的东西,例如 10,会导致大量操作。你有没有乘过两个 9 位数字?使用我们通常在学校学习的方法,这将涉及 81 位数字乘法。但是,Java 将使用一条乘法指令。

大数字(例如 18 位数字)怎么办?对我们来说,这将涉及 324 位乘法。在这里,实现将使用 2 ints,相当于为我们乘以 2 位数字。这将导致 Java.

的 4 个乘法指令

为什么不在Java中使用更大的基数来进一步减少运算次数呢?因为乘法。保证在Java中两个int相乘的结果会在long中,而10亿(10^9)是10的最大次方[= =12=]。这些操作对于 Java 来说仍然非常容易——只需乘法指令即可。可以使用更大的数字,例如 20 亿,或 Integer.MAX_VALUE(略超过 20 亿),但出于人类可读性的目的,该答案选择使用 10 亿。任何大于 Integer.MAX_VALUE 的东西都需要更大范围的东西,但这就是答案已经在尝试做的事情。

此外,在表示中使用较少的 int 可以节省内存使用量。

密码

int decLen = decimal.length();
int bigLen = (decLen-1) / BASE_DECIMAL_DIGITS + 1;

尝试确定在内部表示中需要多少 int 才能将传入数字存储为 String 表示。每个 int 有 9 个十进制数字。我会使用 Math.ceil( (double) decLen / BASE_DECIMAL_POINTS).