【发布时间】:2011-09-09 16:07:06
【问题描述】:
前言
我正在通过编写和改进自己的 BigInt 库来学习计算机数学。到目前为止,我的第一个版本将基数为 10 的数字的每个数字存储在向量的连续元素中。它可以以任意精度进行乘法和加法。我想通过转换为基数 2^x 来使用标准 C++ 数据类型中的所有可用空间来加速它。
信息
我正在从标准输入读取 1000 个或更多数字,以 10 为基数,我希望将它们转换为以 2^x 为基数,因此我可以轻松地将它们存储在标准 C++ 数据类型之一的数组或向量中,可能是无符号整数。我对如何进行基本转换只有一个想法,即用余数重复除法。下面是一些描述该方法的 C++ 代码:
vector<int> digits;
while(num!=0) {
int mod = num%base;
num = num/base;
digits.push_back(mod);
}
难题
我不知道的一些事情是除以余数是否是对大整数进行基数转换的正确方法。我试过看看 GMP 库 是如何做到的。 gmp/mpn/generic/set_str.c 是发生“魔法”的相关 c 源文件,但我不确定那里发生了什么。 Matt McCutchen 的 BigInt 似乎使用了带余数的重复除法。如果我确实使用这种方法,我基本上需要编写我的 BigInt 类的两个版本,一个用于在 Base10 中工作,另一个用于 Base2^x。
结论
- 就将大数从字符串转换为 32 位字数组的正确步骤提供建议。
- 帮助我了解 GMP 如何将字符串转换为 32 位字的数组,而无需涉足许多抽象层。
使用 4 位字长的示例
我们要存储的数字(显然是小号):123456789
无符号字符的范围为 0-255,如果我们想拆分我们的数字并将其存储在向量中,我们可以通过以下三种方式之一进行:
- 以 10 为底,我们的向量看起来像:[1,2,3,4,5,6,7,8,9]
- 这是我的向量在我的第一个实现中的样子。
- 以 100 为底,我们的向量看起来像:[1,23,45,67,89]
- 易于从基数 10 转换为基数 100,具有 ciel(base10/2 中的数字)元素。
- 以 256 为基数,我们的向量如下所示:[7,91,205,21]
显然,第三种解决方案对于内部表示来说是最佳的,也是我想要达到的。
【问题讨论】:
-
您是否将字符串到 bigint 的转换与 bigint 到字符串的转换混淆了?
-
@MarkRansom - 不,我正在尝试读取字符串并将其存储为 bigint。
-
一个 bigint 类可能更适合存储更大的块,而不是更小的块。与其从 10 降到 2,不如升到 2^31-1 之类的更好。
-
C 接口和实现amazon.com/… 这本书有一个完整的工作 bigint 库,详细解释。这不是一本好的书(还可以,只是不例外),但听起来它在这里很适合你。