为什么要使用更高的基数来实现BigInt?

我正在尝试实现BigInt并阅读了一些关于它的线程和文章,其中大多数建议使用更高的基数(256或2 ^ 32甚至2 ^ 64)。

为什么更高的基数有利于此目的?

我有的其他问题是我应该如何将字符串转换为更高的基数(> 16)。 我读过没有标准的方法,除了base64。 最后一个问题,我如何使用这些更高的基础。 一些例子会很棒。

用于乘以或添加适合寄存器的数字的CPU周期往往是相同的。 因此,通过使用整个寄存器,您将获得最少的迭代次数和最佳性能。 也就是说,在32位架构上,使基本单元为32位,在64位架构上,使其为64位。 否则 – 比方说,如果你只填满32位寄存器的8位 – 你就是在浪费周期。

  1. 第一个答案说得最好。 我个人使用base 2 ^ 16来防止乘法溢出。 这允许任何两个数字一起乘以一次而不会溢出。

  2. 转换到更高的基数需要快速除法方法以及尽可能地打包数字(假设你的BigInt lib可以处理多个基数)。

考虑基数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 
  1. ???

你应该有一个Base类来存储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