如何计算阶乘> 31时处理整数溢出

问题描述 投票:-1回答:4

迭代函数返回一个阶乘操作的结果。该代码似乎打破后我试着计算了许多,这将导致整数溢出。我怎样才能最好的处理?难道意义,是它准确吗?超过最高限额每次迭代存储为的功率和返回限制加描述的时候,它可以通过自身相乘量的字符串?

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);
}
c factorial
4个回答
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代替int(但那么你在21左右的限制)(通常是64位),或处理的情况下的值> 16否则。

顺便说一句:如果你真的想成为快,不计算阶乘但使用一个查找表,这是作为练习留给读者。


1
投票

无论是使用long long或尝试,如果可以优化您的计算。

最后,还有一个办法是寻找大整数库。


1
投票

您正在使用符号整数来计算和有符号整数溢出是未定义的行为。所以,无论你的代码返回它根据C标准纠正。通常发生的是,你只是得到正确的结果的低位。其中,因为它是有符号整数,可以是负数。

如果你只是想获得大量的近似结果,那么为什么不改变你的代码中使用双?对于像3小数目!你仍然会得到6,但过去17个左右你喜欢的东西4.643 + E8,这意味着4.643 * 10 ^ 8。双类型将最终耗尽指数,但它可以让你有很多,甚至比无符号长长进一步。


0
投票

为了能够最大因子,你可以使用无符号长长此函数的返回类型。和你的函数是递归式的,运行时间慢则非递归式的。我觉得这里是一个很好的解决方案

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.