这里的第一次海报,我希望这个问题是可以接受的。
作为一个小测试,我编写了一个应用程序,它使用迭代和递归来计算数字的阶乘。除非在尝试计算大于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;
}
感谢您的考虑。
答案 0 :(得分:9)
递归版本计算5 *(4 *(3 *(2 * 1)))
迭代版本计算1 *(2 *(3 *(4 * 5)))
操作顺序的差异会改变浮点运算的舍入方式,从而产生不同的结果。
答案 1 :(得分:5)
double
类型为not an exact type。它有望成为正确值的近似值。
因此不能保证两种实现都是准确的。
正如您的实施所关注的那样, 可以导致不同答案的两个因素。
答案 2 :(得分:2)
乘法的顺序不同,由于浮点舍入而产生不同的结果。
如果您将for
循环更改为1
到i
(而非i
到1
),则应获得相同的结果从递归版本开始。