迭代函数返回阶乘运算的结果。我尝试计算一个将导致整数溢出的数字后,代码似乎中断了。我该如何最好地处理呢?这是否有意义,是否准确?是将超过最大限制的每次迭代都存储为的幂,然后返回该限制以及一个字符串,该字符串描述可以自身乘以的次数?
int ft_iterative_factorial(int nb)
{
int i;
int n;
int res;
i = 1;
n = nb;
res = nb;
while (i < nb)
{
if (nb == 1 || nb == 0)
{
res = 1;
break ;
}
res = res * (n - 1);
i++;
n--;
}
return ((nb < 0 || nb > 31) ? 0 : res);
}
答案 0 :(得分:3)
您的功能真的很复杂。
请考虑以下实施方式:
int ft_iterative_factorial(int nb)
{
int res = 1;
for (int i = 2; i <= nb; i++)
{
res = res * i;
}
return res;
}
您的测试return ( nb < 0 ? 0 : res);
在循环后没有多大意义,您应该在循环前进行,if (nb == 1 || nb == 0)
在循环内也没有意义。但是无论如何,这些测试对我的代码毫无意义。
int
可能是32位类型,而32位不足以存储16位!。
要么使用long long
(通常为64位)而不是int
(但是限制为21左右),否则处理值大于16的情况。
顺便说一句:如果您真的想快点,不要计算阶乘,而要使用查找表,这是读者的练习。 / p>
答案 1 :(得分:1)
使用long long
或尝试优化计算(如果可能)。
最后,一种替代方法是搜索大整数库。
答案 2 :(得分:1)
您正在使用有符号整数进行计算,并且有符号整数溢出是未定义的行为。因此,无论您的代码是什么,都可以根据C标准正确返回。通常会发生的是,您只是得到正确结果的低位比特。由于它是带符号的int,因此可以为负。
如果您只想获得大数的近似结果,那么为什么不更改代码以使用double?对于3之类的小数字!您仍然会得到6,但超过17则得到4.643 + E8,即4.643 * 10 ^ 8。双重类型最终将用完指数,但它比无符号长久还带给您更多的东西。
答案 3 :(得分:0)
对于有能力的最大阶乘,可以将此函数的返回类型使用unsigned long long。而且您的函数是递归样式,运行时间比非递归样式慢。 我认为这是一个很好的解决方案
unsigned long long ft_iterative_factorial(int nb)
{
unsigned long long result = 1;
for (int i = 2; i <= nb; i++)
{
result = result * (unsigned long long)i;
}
return result;
}
int main()
{
cout << ft_iterative_factorial(17) << endl;
return 0;
}