我是C ++的新手,我正在尝试编写一个递归阶乘计算器。我确实写过,但是它为20、21、22、33、40等条目提供了多个负值。而且即使我尝试启用long long int,代码也无法为大于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;
}
最佳答案
您正在经历的是整数溢出导致的不确定行为。您使用的是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
开始,如果使用数字,这将使您获得两倍的范围,因为无符号类型仅处理正数。不过,这只是一个创可贴。为了真正解决该问题,您将需要找到一个执行任意精度整数数学的库。 (bigint库)
(也可以执行一些平台特定的操作来向编译器询问128位int,但是更好的解决方案是切换到bigint数据类型)
编辑:
我应该澄清一下,通过“ bigint”,我不一定是指任何特定的库。正如评论中所建议的,关于可以使用哪个库完成工作的选择有多个。
关于c++ - 递归c++阶乘为多个条目提供负值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42893222/