我得到了这个函数来计算给定整数的阶乘:
long iterFact(long number) {
long factorial = 1;
for (long i = 1; i <= number; i++)
factorial *= i;
return factorial;
}
但是当我传递例如20
作为参数时,它返回一个负数,我认为这是因为数字太长了,但我仍然得到一个负数,结果即使在将所有内容从int
更改为long
。
答案 0 :(得分:3)
您不是添加数字,而是将它们相乘。实际上,你不是计算Fibonacci序列,而是计算阶乘; - )
因子增长非常快:20! (2432902008176640000
)不适合您系统上的long
(32位,可能是Windows),因此其中一个乘法会导致算术溢出,C Standard明确将其描述为未定义的行为。在您的系统上,计算可能以2 ^ 32为模进行,结果可能是负数,但标准不保证这一点。
切换到类型unsigned long long
,保证至少有64位,可以让你计算20!
,但很快就会失败,21!
。实际上2432902008176640000
略小于2 ^ 63-1,因此类型long long
也足够了。
答案 1 :(得分:0)
我认为你的意思是阶乘,而不是斐波那契序列?
在大多数现代系统中,int
和long
都是32位,可以表示最多约20亿的数字。 20阶乘约为2亿亿。尝试使用64位的long long
。
答案 2 :(得分:0)
这是一个整数溢出;因为你的变量是有符号的,并且由于符号位是最重要的,所以在某些时候你会溢出你的变量。实际上,20!是一个巨大的数字。您应该尝试将变量声明为unsigned long,并将其打印出来。
答案 3 :(得分:0)
如果sizeof(long)
是4个字节且LONG_MAX是2 ^ 31 - 1,那么在计算13!
时会出现整数溢出。有符号整数溢出为undefined behaviour.您可以使用不同的数据类型,例如uintmax_t
,它可以包含更大的数字,但仍然不足以处理更大的因子。
查看GMP library。
答案 4 :(得分:0)
这是签名类型的溢出
int 可以是4个字节:-2 147 483 648/2 147 483 647
长可能是8个字节:-9223372036854775808 / 9223372036854775807
int / long可以是签名和未签名的