大数类库的设计与实现

在现代编程中,处理大数(超过64位无符号整数)的需求日益增长,尤其是在密码学和科学计算等领域。本文介绍的是一个C++模板类库,它允许进行任意大小的数字运算,只要系统的内存能够支持。

编译定义

通过定义不同的宏,可以影响类库的编译行为。例如,定义N_MT会包含一个小型的C++线程池库,使得可以在多核处理器上进行并行的加法和乘法运算。默认情况下,库使用std::vector,但如果需要限制内存分配,可以通过定义N_SMALLVECTOR来包含一个LLVM实现的小向量版本。

N类内部机制

N是一个模板类,它接受一个整数参数,这个参数默认为100,表示在堆分配之前的最大数字位数。如果不定义N_SMALLVECTOR,则这个数字被忽略,因为使用的是std::vector。N类存储所有数字位在一个vector中,其中D是unsigned char的别名,代表十进制数组,还有一个基数值(默认为10)和一个布尔标志位来保持符号值。

N的表示和访问

在库的调试版本中,每次操作改变N后,都会调用一个特殊函数来辅助调试。例如,N::operator[](size_t)可以获取最右边的特定数字。如果指定的数字超出了数字的范围,函数不会崩溃,而是返回0。

加法和乘法

加法和乘法通过循环数字来实现。例如,如果两个数字的位数不同,可以通过循环和进位来计算它们的和。在多线程加法中,如果有更多的项需要相加,可以使用线程池。

除法

除法不能在多线程中进行。它返回一个包含商和余数的std::tuple。除法过程涉及到比较和减法,直到余数小于除数。

逻辑操作

逻辑运算符如&、|、^等最终会调用逻辑函数。这些操作需要将N转换为基数2,这在数字很大时意味着需要处理大量的数字位。

内存使用

除了返回std::string的s()函数外,类库的其余部分使用smallvector,这允许在已知数字大小时进行栈分配,并在数字变大时自动切换到堆分配。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485