Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何找到硬件算术完全支持的最大整数?_C++_Math_Arbitrary Precision - Fatal编程技术网

C++ 如何找到硬件算术完全支持的最大整数?

C++ 如何找到硬件算术完全支持的最大整数?,c++,math,arbitrary-precision,C++,Math,Arbitrary Precision,我正在实现一个BigInt类,它必须支持对整数的任意精度运算 引用S.Skiena的“算法设计手册”: 我应该在什么基础上做[编者按:任意精度]算术用十进制实现自己的高精度算术包可能是最简单的,因此可以将每个整数表示为以10位为基数的字符串。然而,使用更高的基数(理想情况下等于硬件算法完全支持的最大整数的平方根)要有效得多 如何找到硬件算法完全支持的最大整数?如果我理解正确,因为我的机器是基于x64的PC,支持的最大整数应该是2^64(http://en.wikipedia.org/wiki/X

我正在实现一个BigInt类,它必须支持对整数的任意精度运算

引用S.Skiena的“算法设计手册”:

我应该在什么基础上做[编者按:任意精度]算术用十进制实现自己的高精度算术包可能是最简单的,因此可以将每个整数表示为以10位为基数的字符串。然而,使用更高的基数(理想情况下等于硬件算法完全支持的最大整数的平方根)要有效得多


如何找到硬件算法完全支持的最大整数?如果我理解正确,因为我的机器是基于x64的PC,支持的最大整数应该是2^64(http://en.wikipedia.org/wiki/X86-64 -体系结构特征:64位整数功能),因此我应该使用base 2^32,但是C++中有没有办法以编程方式获得这个大小?这样我就可以将我的BaseType类型转换为它了?< /P> < p>你可能正在搜索<代码>:
您还可以使用
std::numeric\u limits::max()
UINT\u max
,所有这些都将产生相同的结果。这些值表示的是
无符号
类型的最大容量。e、 g.可存储为无符号类型的最大值

事情不是那么黑白分明。这里可能有一些问题,你可能还有其他值得考虑的事情。我现在已经编写了两个可变精度工具(在MATLAB和中),并且在每个工具中选择了不同的方法。无论您是编写整数形式还是高精度浮点形式,这也很重要

不同的是,整数可以不受位数限制地增长。但是,如果使用用户指定的位数执行浮点实现,则始终知道尾数中的位数。这是固定的

首先,最简单的方法是对每个十进制数字使用一个整数。这使得许多事情都能很好地工作,因此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和double来存储元素,我可以为每个元素存储6个十进制数字。尽管如此,卷积仍然会导致较大数字的溢出

N = repmat(999999,1,10000);
log2(max(conv(N,N)))
ans =
       53.151
因此,长度为10000兆字节(60000个十进制数字)的两组基数1000000兆字节之间的卷积将溢出双精度不能准确表示整数的点

同样,如果你要使用百万位数的数字,要小心。在基于卷积的乘法中使用更高基的migits的一个好处是,因为conv操作是O(n^2),所以从基10到基100的加速比为4-1。以1000为基数会使卷积加速9-1

最后,使用10以外的基数作为migits使得实现保护位(用于浮点)是合乎逻辑的。在浮点运算中,您永远不应该信任计算的最低有效位,因此将一些数字隐藏在阴影中是有意义的。因此,当我编写工具时,我让用户控制要携带多少个数字。这当然不是整数的问题

还有许多其他问题。我在这些工具附带的文档中对它们进行了讨论。

int
(扩展而言,
unsigned int
)是架构的“自然”大小。因此,具有int的一半位的类型应该工作得相当好。除此之外,您还需要为特定的硬件进行配置;存储单元的类型和计算单元的类型应为标头中的typedefs,并选择与特定处理器匹配的类型。通常,您会在运行一些速度测试后进行此选择

INT_MAX在这里没有帮助;它告诉您可以存储在int中的最大值,这可能是硬件可以直接支持的最大值,也可能不是。类似地,INTMAX_MAX也没有帮助;它告诉您可以作为整数类型存储的最大值,但没有告诉您对此类值的操作是否可以在硬件中完成,或者是否需要软件模拟


回到过去,经验法则是对整数的操作直接在硬件中完成,而对long的操作是作为多个整数操作完成的,因此对long的操作要比对整数的操作慢得多。这不再是一个好的经验法则。

64的平方根是32?我以为是8。它是sqrt(2^64)=2^32。我将编辑帖子以使其更清晰。没有问题,顺便说一下,它是完全错误的,不仅仅是模糊的。。。谢谢。@dexpert我知道我将代码编译到一个特定的处理器,事实上我问这个问题是为了让我的代码在每个处理器上使用合适大小的类型。你回答o