它工作到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);
}
答案 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)
号码来自溢出。无符号算术以模数(该类型的最大值)完成,因此一些小数学应该解释为什么你得到你的结果。
有符号整数溢出的结果是未定义的,所以如果你一直在使用有符号整数,你可以得到任何东西(尽管在很多系统上它们可能完全相同)