OverflowError:(34,“数值结果超出范围”)在编写pow(x,n)的自定义实现时

时间:2019-05-07 10:50:36

标签: python-3.x algorithm recursion tail-recursion

在为(x = 2,n = -2147483648)实现pow(x,n)时,出现以下错误:

代码:

class Solution:
    def myPow(self, x, n):
        flag = n < 0
        n = -1 * n if flag else n
        ans = None
        if n % 2 == 0:
            t = pow(x, n/2)
            ans = t*t
        else:
            t = pow(x, (n-1)/2)
            ans = x * t * t
        return (1/ans) if flag else ans

if __name__ == "__main__":
    Solution().myPow(2,-2147483648)

Traceback (most recent call last):
  File "pw.py", line 16, in <module>
    Solution().myPow(2,-2147483648)
  File "pw.py", line 8, in myPow
    t = pow(x, n/2)
OverflowError: (34, 'Numerical result out of range')

但是,当我使用以下代码片段将n / 2和(n-1)/ 2类型转换为int实现相同的功能时,我得到0.0作为输出:

class Solution:
    def myPow(self, x, n):
        flag = n < 0
        n = -1 * n if flag else n
        ans = None
        if n % 2 == 0:
            t = pow(x, int(n/2))
            ans = t*t
        else:
            t = pow(x, int((n-1)/2))
            ans = x * t * t
        return (1/ans) if flag else ans

if __name__ == "__main__":
    Solution().myPow(2,-2147483648)

我无法找出原因,这是由于stackoverflow所致,因为python解释器无法处理尾递归优化,并且返回的结果得以保留,因为稍后将其用于进一步的计算。

我很想知道这两种情况为何不同。

2 个答案:

答案 0 :(得分:3)

在Python 3.x中,

/始终执行浮点数除法,而在Python 2.x中,必须明确地强制转换操作数。因此,type(n/2) == floattype(int(n/2)) == int。或者,您可以使用n // 2,其中//执行下限/整数除法。

如果其中一个参数也是pow,则内置float函数将返回float。在内部,它们是双精度浮点数,可以store up to ~10308 –比2 2147483648/2 小得多,因此比OverflowError小。

答案 1 :(得分:1)

计算后返回的值的大小太大,甚至对于float变量也无法存储,因此会因OverFlowError Exception而出错