使用迭代和递归计算阶乘时的不同答案

时间:2013-04-08 07:09:12

标签: c++ recursion iteration factorial

这里的第一次海报,我希望这个问题是可以接受的。

作为一个小测试,我编写了一个应用程序,它使用迭代和递归来计算数字的阶乘。除非在尝试计算大于24的数字的阶乘时,这似乎工作正常。

例如,在计算24的阶乘时,两种方法都给出正确的答案62044840173323941。

但是,当计算25的阶乘时,答案会有所不同。递归方法的答案为1.5511210043330986e + 025,而迭代方法的答案为1.5511210043330984e + 025。

根据Wolfram Alpha的说法,正确的答案应该与迭代方法相同,那么为什么函数之间的差异呢?我问过我的同事,他们也无法解释这种行为。

#define TEST_CASE 25

double GetFactorialRecursive(double i)
{   
    if (i == 1)
    return i;
    else
    return i * GetFactorialRecursive(i - 1);
}

double GetFactorialIterative(double i)
{
    double result = 1.0;
    for (; i > 0; --i)
        result *= i;
    return result;
}

int main ()
{
    double recres = 0, itrres = 0; 
    recres = GetFactorialRecursive(TEST_CASE);
    itrres = GetFactorialIterative(TEST_CASE);

    if (recres != itrres)
        std::cout << "Error" << "\n";
    std::cout << std::setprecision(25) << "Recursion: " << recres << ", Iteration: " << itrres << "\n";
    return 0;
}

感谢您的考虑。

3 个答案:

答案 0 :(得分:9)

递归版本计算5 *(4 *(3 *(2 * 1)))

迭代版本计算1 *(2 *(3 *(4 * 5)))

操作顺序的差异会改变浮点运算的舍入方式,从而产生不同的结果。

答案 1 :(得分:5)

double类型为not an exact type。它有望成为正确值的近似值。

因此不能保证两种实现都是准确的。

正如您的实施所关注的那样, 可以导致不同答案的两个因素。

  1. 您的订购方式不同。
  2. 您的迭代版本在同一个变量中执行所有数学运算。英特尔兼容的体系结构(x86和x86-64)在其浮点寄存器中使用 80位的精度,并且在寄存器存储在内存中之前一直保持准确性。

答案 2 :(得分:2)

乘法的顺序不同,由于浮点舍入而产生不同的结果。

如果您将for循环更改为1i(而非i1),则应获得相同的结果从递归版本开始。