C中的因子程序在20后是错误的

时间:2016-03-09 13:43:34

标签: c long-integer unsigned factorial

它工作到20但是如果输入21则返回1419745 ...当21阶乘实际上是51090942171709440000时。我假设这是因为无符号长最大值但是这个错误的数字在哪里(141 .. 。)来自,如何让程序计算出更大数的阶乘?

#include <stdio.h>

unsigned long fact(unsigned long input);

int main()

{

    int input;

    printf("Enter an integer to find the factorial of: ");
    scanf(" %d", &input);

    printf("The Factorial of %d = %lu\n" , input, fact(input)); 

    return 0;
}

unsigned long fact(unsigned long input)
{
    if (input == 0)
            return 1;
    else    
        return input * fact(input - 1);
}

2 个答案:

答案 0 :(得分:3)

这只回答了你问题的一半(为什么它会这样运作)。

您得到的结果是21! mod 2^64。这是因为您使用的是64位系统,21!大于可以作为64位无符号整数存储的最大数。

您为大于或等于21的值计算的所有因子都是错误的;它们不能用64位整数表示,因为它们比它长。

您可以尝试使用unsigned long long作为函数fact()返回的值的类型(并使用printf()更改为%lu格式字符串%llu );它可能有所帮助,但这取决于一些因素。例如,它对我的​​架构没有帮助。

您可以通过查看sizeof(unsigned long long)返回的值来了解它是否可以帮助您。如果if是8那么你运气不好。 20是您可以在该系统上计算因子的最大数字。

如果你的目的是计算阶乘,那么你必须使用一个知道如何处理大数的库。但是,如果您需要其他计算的阶乘(例如,对于combinations),那么您可以尝试避免生成大数并找到将每个乘法与除法匹配的方法。这样,您使用的数字的大小介于64位整数的限制之间,您可以超过21

或者您可以使用double而不是整数,但您又重新开始营业,但精度不高。大浮点数正确存储数字的大小及其第一个数字。最后的数字丢失了。

我最近没有在C / C ++中编程很多,我不推荐你一个可以帮助你用大数字进行计算的库: - (

答案 1 :(得分:-1)

号码来自溢出。无符号算术以模数(该类型的最大值)完成,因此一些小数学应该解释为什么你得到你的结果。

有符号整数溢出的结果是未定义的,所以如果你一直在使用有符号整数,你可以得到任何东西(尽管在很多系统上它们可能完全相同)