大整数类 BigInt
Posted izlyforever
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大整数类 BigInt相关的知识,希望对你有一定的参考价值。
把自己的 个人C++17代码模板库 放在 github 后,发现没有 BigInt,于是有了这篇博客,搜了一下相当有的几个例子,发现都不够全面,或者说不够高效,于是就自己尝试一下。那么就有几个问题
- 用什么存数据
- 内部逻辑几进制
- 乘法和除法怎么实现
- 最终哪些功能要实现
- 与 Boost 的大数比较性能如何
代码仓库,这里就当作放文档的地方吧
存储
首先肯定会用类似多项式方式存大数,自然会想到用 vector<T>
,现在问题是 \\(T\\) 是什么
- 不能是 bool,因为
vector<bool>
不是容器,水很深,我把握不住。 char, short, int, long long
选什么呢?因为我要用 NTT,因此只能在 int 和 long long 中选择,但是如果用long long
基础乘法时不可避免出现__int128
十分影响效率,最终选择int
- 有符号还是无符号:有符号,因为在出现 NTT 会出现减法,此时很可能就会模 \\(2^{32}\\) 直接爆炸
再用一个 flag 存储符号。
逻辑
先继承 vector<int>
然后用 sgn
存储符号。
- 取负号,自己改变符号(为了高效),
+
也太鸡肋了就不搞了,判断是否相等 - 实现大小比较
- 实现加法减法
- 实现逻辑比较
- 用 NTT 实现乘法
- 用 牛顿法实现除法
由于 NTT 的使用中,能选取的最佳模数为 \\(469762049 = 7 \\cdot 2^{26} + 1\\) 又由于 \\(2^{2^{25}} \\simeq 10^{10^7}\\) ,所以数的十进制表示长度不能超过 \\(10^7\\)(其实如果超过了一次除法,甚至乘法估计也是跑不动的)
基础功能
+=,-=,*=,/=
++,--
(前缀),后缀版本太蠢了- 位运算
- 与基础数据交互,类型转化
int, LL, string
- IO
- 支持 lg(2 为底数)
拓展功能
- gcd,lcm, pow,sqrt,cbrt,任意次开方
- 静态:big_random: 利用 mt19937?
与 Boost 比较
#include <boost/multiprecision/cpp_int.hpp>
using BINT = boost::multiprecision::cpp_int;
以上是关于大整数类 BigInt的主要内容,如果未能解决你的问题,请参考以下文章
超出JavaScript安全整数限制的数字计算-BigInt