如何找到硬件算法完全支持的最大整数
How do I find the largest integer fully supported by hardware arithmetics?
我正在实现一个BigInt类,该类必须支持对整数的任意精度运算。
引用S.Skiena的"算法设计手册":
我应该做什么基础[编者按:任意精度]算术-用十进制实现自己的高精度算术包可能是最简单的,因此可以将每个整数表示为以10为基数的字符串。然而,使用更高的基数要有效得多,理想情况下等于硬件算术完全支持的最大整数的平方根。
如何找到硬件算术完全支持的最大整数?如果我理解正确,作为一台基于x64的电脑,支持的最大整数应该是2^64(http://en.wikipedia.org/wiki/X86-64-体系结构功能:64位整数功能),所以我应该使用base2^32,但在c++中有没有一种方法可以通过编程获得这个大小,这样我就可以为它键入base_type?
您可能正在搜索std::uintmax_t
和std::intmax_t
。
static_cast<unsigned>(-1)
是最大int。例如,所有位都设置为1
。这就是您想要的吗?
您也可以使用std::numeric_limits<unsigned>::max()
或UINT_MAX
,所有这些都将产生相同的结果。并且这些值所表示的是CCD_ 7类型的最大容量。例如可以存储为无符号类型的最大值。
int
(扩展为unsigned int
)是体系结构的"自然"大小。因此,一个具有int一半位的类型应该工作得相当好。除此之外,您还需要针对特定的硬件进行配置;存储单元的类型和计算单元的类型应当是报头中的typedefs,并且选择它们的类型以匹配特定处理器。通常情况下,您会在运行一些速度测试后做出此选择。
INT_MAX在这里没有帮助;它告诉可以存储在int中的最大值,这可能是硬件可以直接支持的最大值也可能不是。同样,INTMAX_MAX也无济于事;它告诉您可以存储为积分类型的最大值,但不告诉您对这样的值的操作是否可以在硬件中完成或需要软件模拟。
在过去,经验法则是直接在硬件中对int进行操作,而对long的操作是作为多个整数操作进行的,因此对long进行的操作比对int的操作慢得多。这不再是一个好的经验法则。
事情并不是那么非黑即白。这里有五月的问题,你可能还有其他值得考虑的事情。我现在已经编写了两个可变精度工具(在MATLAB、VPI和HPF中),并在每个工具中选择了不同的方法。这也关系到你是在写整数形式还是高精度浮点形式
不同的是,整数可以在没有位数限制的情况下增长。但是,如果您使用用户指定的位数执行浮点实现,那么您总是知道尾数中的位数。这是固定的。
首先,对每个十进制数字使用一个整数是最简单的。这使得很多事情都能很好地工作,所以I/O很容易。不过,它在存储方面有点低效。不过,加减法很简单。如果你对每个数字使用整数,那么乘法就更容易了。例如,在MATLAB中,conv是相当快的,尽管它仍然是O(n^2)。我认为gmp使用fft乘法,所以速度更快。
但是,假设您使用基本的conv乘法,那么您需要担心具有大量数字的数字会溢出。例如,假设我将十进制数字存储为8位有符号整数。使用conv,后面跟着进位,我可以做乘法。例如,假设我的数字是9999。
N = repmat(9,1,4)
N =
9 9 9 9
conv(N,N)
ans =
81 162 243 324 243 162 81
因此,即使要形成9999*9999的乘积,我也需要小心,因为数字会溢出一个8位有符号整数。如果我使用16位整数来累积卷积乘积,那么一对1000位整数之间的乘积可能会导致溢出。
N = repmat(9,1,1000);
max(conv(N,N))
ans =
81000
因此,如果你担心数百万数字的可能性,你需要小心。
一种选择是使用我所说的migits,基本上是在高于10的基数下工作。因此,通过使用基数1000000和doubles来存储元素,我可以为每个元素存储6个十进制数字。不过,对于较大的数字,卷积仍然会导致溢出。
N = repmat(999999,1,10000);
log2(max(conv(N,N)))
ans =
53.151
因此,长度为10000 migits(60000位十进制数字)的两组基数为1000000的migits之间的卷积将溢出双精度不能准确表示整数的点。
所以,如果你要使用数百万位数的数字,要小心。在基于卷积的乘法中使用更高基的migits的一个好处是,由于conv运算是O(n^2),那么从基数10到基数100会使速度提高4-1。以1000为基数会在卷积中产生9-1的加速。
最后,使用10以外的基数作为migits使实现保护数字(用于浮点运算)变得合乎逻辑。在浮点运算中,您永远不应该相信计算的最低有效位,因此将几个数字隐藏在阴影中是有意义的。因此,当我编写HPF工具时,我让用户控制将携带多少数字。当然,这不是整数的问题。
还有许多其他问题。我在这些工具附带的文档中讨论了它们。
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- FlatBuffers/Protobuf 中是否有支持任意 24 位有符号整数定义的可移植二进制序列化架构?
- 编译器警告(CodeBlocks/wxwidget):您的编译器似乎不支持64位整数,而是使用仿真类
- 任意精度无符号整数,仅支持后递增运算符
- 如何找到硬件算法完全支持的最大整数
- 错误 1 错误 C4430:缺少类型说明符 - 假定为 int.注意:C++不支持默认整数
- 需要一个支持 16 位整数 (c++) 的免费线程安全矩阵数学库
- 32位操作系统支持64位无符号整数!!如何
- 模板类:错误 C4430:缺少类型说明符 - 假定为 int.注意:C++不支持默认整数
- 错误 C4430、C2146 - 缺少类型说明符 - 假定为 int.注意:C++不支持默认整数
- srand(time(NULL)):错误 C4430:缺少类型说明符 - 假定为 int.注意:C++不支持默认整数
- C++参数支持字符串和整数的结构
- c++支持原生无符号整数,而java不支持的优点是什么?
- boost::variant是否支持64位整数
- 32位处理器如何支持64位整数