我是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/

10-16 19:02