当我添加正数时,为什么我的函数会返回负数?

时间:2017-01-21 19:43:42

标签: c++

我得到了这个函数来计算给定整数的阶乘:

long iterFact(long number) {
    long factorial = 1;

    for (long i = 1; i <= number; i++)
        factorial *= i;

    return factorial;
}

但是当我传递例如20作为参数时,它返回一个负数,我认为这是因为数字太长了,但我仍然得到一个负数,结果即使在将所有内容从int更改为long

5 个答案:

答案 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)

我认为你的意思是阶乘,而不是斐波那契序列?

在大多数现代系统中,intlong都是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

另外:What is the simplest way of implementing bigint in C?

答案 4 :(得分:0)

这是签名类型的溢出

int 可以是4个字节:-2 147 483 648/2 147 483 647

可能是8个字节:-9223372036854775808 / 9223372036854775807

int / long可以是签名和未签名的