• C++
  • C++ 高精度阶乘算法

  • @ 2025-5-16 11:54:52

C++ 高精度阶乘算法教程(0基础通俗易懂)

📚 什么是高精度阶乘?

在C++中,像 intlong long 这样的基本数据类型都有表示范围的限制。例如:

  • long long 最大只能表示约 9e18(即 9,223,372,036,854,775,807)
  • 100!(100 的阶乘)是一个非常大的数,远远超过这个范围!

所以我们需要自己实现一个高精度阶乘算法,也就是用字符串或数组来模拟大数的乘法运算。


🧠 基本思路:模拟竖式乘法 + 循环累乘

我们要计算的是:

n! = 1 × 2 × 3 × ... × n

虽然每次都是乘一个小整数,但我们可以使用高精度乘法的基本思想来模拟整个过程。

关键点:

  • 使用 vector<int> 来存储每一位数字(便于处理进位)
  • 每次将当前结果乘以一个整数 i(i 从 1 到 n)
  • 实现一个简单的“大数 × 小整数”的函数即可

💡 数据结构选择:vector

我们把数字逆序存储在一个 vector<int> 中,这样便于从个位开始操作。

例如:

string num = "123";
vector<int> digits;
for (int i = num.size() - 1; i >= 0; i--)
    digits.push_back(num[i] - '0');
// digits = {3, 2, 1}

💻 示例代码(完整可运行)

#include <iostream>
#include <vector>
using namespace std;

// 打印结果
void print(const vector<int>& v) {
    for (int i = v.size() - 1; i >= 0; i--)
        cout << v[i];
    cout << endl;
}

// 高精度乘法:大数 × 小整数(比如:当前结果 × i)
vector<int> multiply(const vector<int>& a, int b) {
    vector<int> res;
    int carry = 0;

    for (int digit : a) {
        int product = digit * b + carry;
        res.push_back(product % 10);
        carry = product / 10;
    }

    // 处理最后可能的进位
    while (carry > 0) {
        res.push_back(carry % 10);
        carry /= 10;
    }

    return res;
}

// 计算 n!
vector<int> factorial(int n) {
    vector<int> result = {1}; // 初始化为 1

    for (int i = 2; i <= n; i++) {
        result = multiply(result, i);
    }

    return result;
}

int main() {
    int n;
    cout << "请输入一个正整数 n:";
    cin >> n;

    if (n < 0) {
        cout << "负数没有阶乘!" << endl;
        return 0;
    }

    vector<int> fact = factorial(n);

    cout << n << "! = ";
    print(fact);

    return 0;
}

📖 示例运行

输入:

请输入一个正整数 n:20

输出:

20! = 2432902008176640000

再试一个更大的:

输入:

请输入一个正整数 n:50

输出:

50! = 3041409320171337658886625767122359663386444873594648677336130547477777947257840705330671441241061776870292595687968000

✅ 总结知识点

内容 说明
使用 vector 存储每一位数字,方便处理进位
逆序存储 从个位开始计算,符合手算习惯
高精度乘法 实现了一个“大数 × 小整数”的函数
阶乘逻辑 从 1 累乘到 n,每次都调用 multiply 函数
输出方式 逆序打印 vector 中的每一位

🧪 练习建议

你可以试着扩展以下功能:

  • 支持更大数(如 n=10000),优化性能
  • 把结果写入文件保存
  • 统计执行时间,看看不同 n 对性能的影响
  • 实现一个函数,把 vector<int> 转成字符串返回

📌 进阶学习建议

如果你已经掌握高精度阶乘,可以尝试挑战:

  • 高精度幂运算(a^b)
  • 高精度平方根(√n)
  • 高精度组合数(如 C(n, k))
  • 使用类封装你的高精度库(面向对象编程)

📚 附录:常见阶乘值(供参考)

n n! 的位数
10 7 位
20 19 位
50 65 位
100 158 位
1000 2568 位
10000 35660 位

如果你希望我继续扩展以下内容,请告诉我:

  • 如何优化高精度阶乘的性能?
  • 如何支持浮点数阶乘(伽马函数)?
  • 如何把结果转成字符串返回?
  • 如何实现高精度排列数 P(n, k)?

😊

0 条评论

目前还没有评论...