递归 C++ 阶乘为多个条目提供负值

  • 本文关键字:C++ 阶乘 递归 c++
  • 更新时间 :
  • 英文 :


我对C++有点陌生,我正在尝试编写一个递归阶乘计算器。我确实写过,但它为 20、21、22、33、40 等条目提供了多个负值。而且代码也无法计算大于 65 的整数的阶乘,尽管我尝试启用长整型。有人可以向我解释为什么会发生这种情况吗?我在python中没有任何问题。为什么它会发生在 C++ 中?

这是我的代码:

#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
long long int factorial(long int n) {
long long int temp;
if (n == 1 || n == 0) {
return 1;
}
else {
temp = n*factorial(n - 1);
return temp;
}
}
int main()
{
int n, i;
cout << "Enter positive integer or zero: ";
cin >> n;
while (n < 0 || cin.fail()) {
cout << "nFactorial cannot be calculated for n is negative." << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), 'n');
cout << "Please try with integer >= 0: ";
cin >> n;
}
cout << factorial(n) << endl;
_getch();
return 0;
}

这是简单的溢出问题。您已经知道 python 的结果,因此您可以检查它对于您正在使用的类型是否太大(显然是)。

至于python,它有内置的支持:在Python中处理非常大的数字。

使用C++ bigint 库。

您遇到的是整数溢出导致的未定义行为。 您正在使用的long long int是最有可能表示为 8 字节整数的有符号整数(这是特定于平台的)。

假设从这里开始,您的long long int只有 8 个字节(64 位),这意味着它可以存储的最大正值约为2^63,约为9.223372037e+18.

尝试计算 20、21、22、33、40 等数字的阶乘将导致值大于long long int可以存储的最大值,这将导致未定义的行为,在这种情况下表现为整数环绕。

要解决此问题,您需要使用表示较大值的整数数据类型capabale。我会首先切换到一个unsigned long long int,如果数字,它会让你得到两倍的范围,因为无符号类型只处理正数。不过,这只是这个问题的创可贴。要真正处理这个问题,你需要找到一个执行任意精度整数数学运算的库。

(您还可以做一些特定于平台的事情来要求编译器提供 128 位 int,但更好的解决方案是切换到 bigint 数据类型)

编辑:

我应该澄清一下,我所说的"bigint"不一定是指任何特定的库。正如评论中所建议的,关于可以使用哪个库来完成工作有多种选择。

最新更新