int和long long因位宽固定(32/64位)易静默溢出,无法准确表示如50!或2^100等大数;高精度需字符串模拟竖式运算,加法逐位进位,乘法双循环定位i+j位,注意去前导零。

为什么 int 和 long long 不够用
因为 C++ 内置整型有固定位宽:int 通常 32 位(最大约 21 亿),long long 一般 64 位(最大约 9×10¹⁸)。一旦运算结果超过这个范围,就会静默溢出——不报错、不警告,只保留低比特位,结果完全错误。比如计算 factorial(50) 或 2^100,直接用内置类型得到的只是个毫无意义的余数。
手写高精度加法和乘法的关键点
核心思路是把大数当字符串存,按位模拟竖式运算。加法相对简单,乘法则容易漏掉进位或错位。
- 加法:从末位开始逐位相加,用
carry记录进位,结果字符数组要预留一位防最高位进位 - 乘法:必须两层循环,外层遍历乘数每一位,内层遍历被乘数每一位;结果位置是
i + j(从右往左索引),不是i * j - 别忘了最后去除前导零,但至少保留一位(如结果为 0)
- 负号单独处理,先取绝对值运算,再根据符号规则补上
示例片段(加法核心逻辑):
string add(string a, string b) {
if (a.length() <h3>用 <code>boost::multiprecision::cpp_int</code> 真正省事吗</h3><p>能用,但要注意它不是“零成本抽象”。<code>cpp_int</code> 默认是动态分配的任意精度整数,小数值也会触发堆内存分配,性能比原生类型慢一个数量级以上。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 若只做少量大数运算(如密码学参数验证),开销可接受
- 若在循环里高频使用(如 DP 中每步都算大数),会显著拖慢速度,且可能引发频繁内存分配抖动
- 编译需链接 Boost,部分嵌入式或竞赛环境不支持
- 输出时默认不带前导零,但输入字符串不能含空格或非法字符,否则构造失败静默转为 0
基本用法:
#include <boost> using namespace boost::multiprecision; cpp_int a = "12345678901234567890"; cpp_int b = 98765432109876543210; cout <h3>竞赛或刷题中该选哪种方案</h3> <p>国内 OJ(如洛谷、Codeforces)几乎都不允许用 Boost,必须手写。而且题目往往只要求输出结果某几位(如最后 100 位)、或模某个数,这时根本不需要完整高精度。</p> <ul> <li>如果只需模 <code>10^k</code>,用 <code>long long</code> 配合每步取模即可(注意乘法中间结果可能溢出,用 <code>__int128</code> 或分治取模)</li> <li>如果只需判断大小或比较,可存为字符串按长度和字典序比较</li> <li>真要输出完整十进制结果,且位数可控(≤ 10⁴),手写 vector<int> 存 1000 进制比存单数字更省内存、更快</int> </li> <li>别在 <code>operator+</code> 里反复 <code>push_back</code> 字符——预分配空间或逆序计算再反转</li> </ul> <p>最常被忽略的一点:输入的大数字符串可能含前导零,但手写运算时若没清除,会导致长度误判,尤其在减法和除法中引发下标越界或死循环。</p></boost>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










