python - 为什么递归改变结果?

标签 python tail-recursion doctest

我正在查看 doctest并将阶乘示例复制到我的编辑器中。因为使用递归感觉更像是函数式编程,所以我想把例子改成这样;

def factorial(n):
    # ... omitted
    if n+1 == n:  # catch a value like 1e300
        raise OverflowError("n too large")

    if n == 0:
        return 1
    else:
        return factorial(n  - 1) * n

此更改后,其中一个测试失败;

Failed example:
    factorial(30.0)
Expected:
    265252859812191058636308480000000L
Got:
    2.6525285981219103e+32

造成这种差异的原因是什么?

最佳答案

尝试使用 factorial(30) 运行而不是 factorial(30.0) .浮点加法与整数加法不完全相同,因此您会在一段时间后开始看到错误。

考虑:

>>> 1e20 + 1 == 1e20 #True

这是因为您没有足够的精度(位)来唯一地存储这两个数字。 (一个典型的 python float 有 64 位,这意味着你有 2**64 个独特的组合——大约在 1.84e19 选项。但是,python float 的最大大小是 sys.float_info.max,在大多数系统上大约是 1.8e308,所以没有办法唯一地存储每个整数值——尤其是当你认为 float 可以容纳的不仅仅是整数值时)

就个人而言,我只是将 n 的值转换为阶乘函数中的整数,因为阶乘仅为整数定义——可能会检查以确保 abs(int(n) - n) < 1e-5或类似的东西。

关于python - 为什么递归改变结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12197923/

相关文章:

python - 在 doctest (python) 中模拟 Y of (from X import Y)

python - 总结列表时出现 TypeError : 'int' object is not callable, - Python

Haskell:改进我的尾递归斐波那契实现

list - 如何递归地添加 F# 列表中的所有元素?

javascript - 堆栈安全的相互递归,不会在调用端泄露实现细节

python - 有没有办法只执行文档测试,而忽略打印函数调用?

python - 动态创建对象的 Doctest

python - TypeError : argument 1 must be pygame. Surface,而不是 str 如何修复?

python - 将查询合并为一个,然后按日期排序

python - 如何真正将窗口置于所有窗口之上——Linux PyGTK