C++中如何处理大整数运算?(通常需要依赖GMP或Boost等库)

标准C++不支持大整数是因为内置类型位宽固定且标准库未提供任意精度整数;GMP是成熟方案,需安装、包含、链接-lgmpxx和-lgmp。

为什么标准C++不支持大整数?

因为 intlong long 等内置类型有固定位宽(如64位最多表示约9.2×10¹⁸),超出就溢出,且C++标准库没提供任意精度整数。你写 a + b 时编译器只做机器字长运算,不会自动扩展——这不是bug,是设计选择。

用GMP最直接:安装后三步就能算

GMP(GNU Multiple Precision)是C/C++里最成熟的大整数方案,性能高、接口稳定。注意它本质是C库,C++用法稍作封装即可:

  • 安装:Ubuntu上 sudo apt install libgmp-dev;macOS用 brew install gmp
  • 头文件用 #include (不是 gmp.h),它提供 mpz_class 类型
  • 链接时加 -lgmpxx -lgmp,缺 -lgmp

    xx
    会报 undefined reference 到 mpz_add 等符号
#include 
#include 

int main() {
    mpz_class a = "123456789012345678901234567890";
    mpz_class b = "987654321098765432109876543210";
    std::cout << a + b << "\n"; // 直接用 +、*、<< 等操作符
}

Boost.Multiprecision是C++风格替代方案

如果你不想引入C风格的GMP,或项目已用Boost,boost::multiprecision::cpp_int 更“像C++”:头文件即用、无显式链接、支持模板参数控制内存策略。但默认是动态分配,小数运算比GMP略慢。

  • 头文件:#include
  • 类型名是 boost::multiprecision::cpp_int,可起别名简化:using bigint = boost::multiprecision::cpp_int;
  • 从字符串构造必须用引号:cpp_int x("12345678901234567890");,写成 cpp_int x(12345678901234567890); 会先被编译器截断成 long long
  • 除法默认截断(类似C++整数除法),要高精度浮点结果得转 cpp_dec_float

手写简单大整数只适合教学,别用在生产环境

网上有些用 vector 存各位数字的手动实现,看似能绕过依赖,但实际问题很多:

  • 乘法复杂度容易写成 O(n²) 甚至更差,GMP用Toom-Cook或FFT,百万位乘法快几个数量级
  • 没处理负数、前导零、进位边界、不同进制输入输出等细节,一跑真实数据就崩
  • 无法和现有代码互操作——比如你写的 BigNum 类没法直接传给需要 mpz_t* 的加密库函数

真正需要可控或嵌入式场景,优先考虑GMP的裁剪版(configure --disable-assembly),而不是重造轮子。