为什么要使用更高的基数来实现 BigInt
Why to use higher base for implementing BigInt?
我正在尝试实现 BigInt,并阅读了一些关于它的帖子和文章,其中大多数建议使用更高的基数(256 或 232 甚至 264)。
为什么更高的基数有利于这个目的?
我的另一个问题是我应该如何将字符串转换为更高的基数(>16)。我读到没有标准方法,除了 base64。最后一个问题,我如何使用这些更高的基数。一些例子会很棒。
以或相加适合寄存器的数字所花费的 CPU 周期往往是相同的。因此,通过用完整个寄存器,您将获得最少的迭代次数和最佳性能。也就是说,在 32 位体系结构上,将基本单元设为 32 位,在 64 位体系结构上,将其设为 64 位。否则,如果你只填满32位寄存器的8位,你就是在浪费周期。
-
第一个答案最好地说明了这一点。我个人使用基数 2^16 来防止乘法溢出。这允许任何两位数乘以一次而不会溢出。
-
转换为更高的基数需要快速除法以及尽可能多地打包数字(假设您的 BigInt 库可以处理多个基数)。
考虑基数 10 ->基数 2。实际转换为 10 -> 10000 -> 32768 -> 2。这可能看起来很慢,但从基数 10 转换为 10000 非常快。在 10000 和 32768 之间进行转换的迭代量非常快,因为要迭代的数字很少。开箱 32768 到 2 也非常快。
因此,首先将基地打包到它可以到达的最大基地。为此,只需将数字组合在一起即可。此基数应为 <= 2^16 以防止溢出。
接下来,将数字组合在一起,直到它们>=目标基数。从这里开始,使用通常在任何其他情况下都会溢出的快速除法算法除以目标基数。
一些快速代码
if (!packed) pack()
from = remake() //moves all of the digits on the current BigInt to a new one, O(1)
loop
addNode()
loop
remainder = 0
remainder = remainder*fromBase + from.digit
enter code here`exitwhen remainder >= toBase
set from = from.prev
exitwhen from.head
if (from.head) node.digit = remainder
else node.digit = from.fastdiv(fromBase, toBase, remainder)
exitwhen from.head
快速除法一瞥
loop
digit = remainder/divide
remainder = remainder%divide
//gather digits to divide again
loop
this = prev
if (head) return remainder
remainder = remainder*base + digit
exitwhen remainder >= divide
digit = 0
return remainder
最后,如果应该打开包装,请打开包装
包装只是将数字组合在一起。
基数 10到基数 10000 的示例
4th*10 + 3rd
*10 + 2nd
*10 + 1st
- ???
你应该有一个基类,用于存储 toString 的字母 + 大小。如果 Base 无效,则只需在逗号分隔的列表中显示数字。
所有方法都应该使用 BigInt 的当前基数,而不是某个常量。
就这样?
从那里,您将能够执行以下操作:
BigInt i = BigInt.convertString("1234567", Base["0123456789"])
其中 [] 重载,将创建一个新基或返回已创建的基。
您还可以执行以下操作:
i.toString()
i.base = Base["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
i.base = 256
i.base = 45000
等^_^。
另外,如果您使用的是整数并且希望能够返回 BigInt 余数,则除法可能会变得有点棘手 =P,但这仍然很容易^_^。
这是我用vjass编写的BigInt库(是的,对于魔兽争霸3,哈哈,不要评判我)
像TriggerEvaluate(evalBase)
这样的事情只是为了防止线程崩溃(邪恶的操作限制)。
祝你好运:D
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- BigInt 类在C++中良好而基本的实现
- 为什么要使用更高的基数来实现 BigInt
- BigInt实现-将字符串转换为存储为无符号int的二进制表示