C++函数计算阶乘返回负值

标签 c++ algorithm factorial integer-overflow

我编写了一个 C++ 函数来计算阶乘,并用它来计算 22C11(组合)。我已经声明了一个变量 ans 并将其设置为 0。我试图计算

22C11 = fact(2*n)/(fact(n)*fact(n))

我将 n 发送为 11 的地方。出于某种原因,我在答案中存储了一个负值。我该如何解决这个问题?

long int fact(long int n) {
    if(n==1||n==0)
        return 1;
    long int x=1;
    if(n>1)
    x=n*fact(n-1);
    return x;
}

main函数中包含以下几行:

long int ans=0;
    ans=ans+(fact(2*n)/(fact(n)*fact(n)));
cout<<ans;

我得到的答案是 -784 正确答案应该是705432

注意:此函数在 n<=10 时工作得很好。我已经尝试使用 long long int 而不是 long int,但它仍然无法正常工作。

最佳答案

实际计算阶乘是不明智的——它们增长得非常快。通常,对于组合公式,最好寻找一种方法来重新排序操作以在一定程度上限制中间结果。

例如,让我们看一下(2*n)!/(n!*n!)。它可以重写为 ((n+1)*(n+2)*...*(2*n))/(1*2*...*n) == (n+1)/1 * (n+2)/2 * (n+3)/3 ... * (2*n)/n。通过交错的乘法和除法,降低了中间结果的增长速度。

所以,像这样:

int f(int n) {
  int ret = 1;
  for (int i = 1; i <= n; ++i) {
    ret *= (n + i);
    ret /= i;
  }
  return ret;
}

Demo

关于C++函数计算阶乘返回负值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35053226/

相关文章:

c++ - 使用 sockaddr_un 调用 connect(2) 时出现编译器错误

arrays - 在线性空间中存储成对和

arrays - 在 n 项数组中查找 k 最小数字的算法

rust - 递归函数计算阶乘导致栈溢出

c++ - 我正在尝试递归地实现一个程序。我只是不明白为什么我的最后一行被执行了两次

java - 使用循环计算阶乘数,Java

c++ - 在linux中输入包含希腊字符的字符串

c++ - 为什么C++ 11不允许使用auto进行直接列表初始化

c++ - 使用 () 或 {} 正确初始化现代 C++(C++11 及更高版本)中的变量?

具有最小大小约束的聚类算法