为何Python递归深度上限为2**31-31而非2**31-1?
Python递归深度上限的奇怪限制:为何是2³¹-31而非2³¹-1?
在Python里,递归嵌套太深会触发RecursionError,可以用sys.getrecursionlimit()查看当前递归深度上限,默认是1000或1500。用sys.setrecursionlimit(LIMIT)可以调整这个上限,但测试发现当设置值超过2³¹-31时,会触发OverflowError: Python int too large to convert to C int。按常识,32位有符号整数最大值是2³¹-1,为什么实际能设置的上限要在此基础上减31?测试环境为Python 3.9.13和3.12(64位Windows),测试过程如下:
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license()" for more information. >>> import sys >>> v = 2**31-1 >>> print(v) 2147483647 >>> sys.setrecursionlimit(v) Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> sys.setrecursionlimit(v) OverflowError: Python int too large to convert to C int >>> v = 2**31-30 >>> sys.setrecursionlimit(v) Traceback (most recent call last): File "<pyshell#5>", line 1, in <module> sys.setrecursionlimit(v) OverflowError: Python int too large to convert to C int >>> v = 2**31-31 >>> sys.setrecursionlimit(v) >>>
原因解析
- 本质上,
sys.setrecursionlimit传入的值并非直接作为C层的栈上限,Python解释器内部会为自身的基础栈帧预留固定空间(比如初始调用栈、异常处理栈等必要开销),这个预留的偏移量就是31。 - 当你设置的LIMIT值超过
2³¹-1 - 31时,经过内部计算后,实际要存入C int类型变量的值会超出32位有符号整数的范围,从而触发溢出错误。 - 哪怕是64位Python,在Windows平台下,由于编译器或历史兼容原因,部分内部栈相关变量仍然使用32位int类型,所以依然受这个限制约束。
内容的提问来源于stack exchange,提问作者Twistios_Player
相关产品推荐
相关产品推荐

