long long 存不下50!因其值约3.04×10⁶⁴,远超其上限9.22×10¹⁸;需用vector模拟十进制大数,逆序存各位并实现竖式乘法。

为什么 long long 存不下 50!?
因为 50! ≈ 3.04 × 10⁶⁴,远超 long long 的最大值(约 9.22 × 10¹⁸)。C++ 标准类型没有内置大整数支持,必须自己模拟“竖式乘法”——把数字拆成数组或字符串的每一位,逐位计算、进位、存储。
用 vector 模拟十进制大数最实用
比字符串操作快,比自定义结构轻量,且天然支持动态扩容。关键不是存“整个数”,而是存“个位、十位、百位……”逆序排列(digits[0] 是个位),方便进位处理:
vectorfactorial(int n) { vector res = {1}; // 初始为 1 for (int i = 2; i <= n; ++i) { int carry = 0; for (int j = 0; j < res.size(); ++j) { int product = res[j] * i + carry; res[j] = product % 10; carry = product / 10; } while (carry) { res.push_back(carry % 10); carry /= 10; } } return res; // 逆序存储:{1,2,3} 表示 321 }
- 每次乘
i都从低位开始扫,边算边更新当前位和进位 -
res大小会动态增长,无需预估位数 - 输出时要倒序遍历:
for (auto it = res.rbegin(); it != res.rend(); ++it) - 别用
vector节省空间——整型运算更安全,现代内存足够
遇到 10000! 这种规模怎么办?
纯十进制模拟会变慢(O(n²) 时间),但多数教学/竞赛场景下 10000! 仍可在毫秒级完成。若真卡性能:
- 改用 base 10000 存储:每个
int存 4 位,减少循环次数,进位逻辑稍调(% 10000// 10000) - 避免频繁
push_back:可预估位数(斯特林公式粗略估算 log₁₀(n!) ≈ n log₁₀(n/e) + log₁₀(√2πn)),reserve 空间 - 不用
string做中间结果——字符串拼接和转换开销大,且易出错
输出或转字符串时容易漏掉前导零?
不会——因为你的 vector 只存有效数字,push_back 的都是非零进位余数,最高位永远非零。唯一要注意的是:如果结果是 0(比如 0!),得单独处理,否则空 vector 会崩。
立即学习“C++免费学习笔记(深入)”;
真正容易被忽略的是:大数阶乘末尾零的个数 ≠ 直接数结果里的 0;那是由因子 5 和 2 的对数决定的,和存储方式无关。但如果你只是要“正确显示全部数字”,vector 逆序法已经够稳——只要别在循环里写错 j 的边界或进位清零逻辑。










