为什么这个 python 代码抛出 OverflowError?

问题描述 投票:0回答:1

今天在做leetcode 50 MyPow ,决定用递归来实现。我的代码如下:


class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n > 0:
            return self.recur(x, n)
        else:
            return 1.0 / self.recur(x, -n)

    def recur(self, x: float, n: int) -> float:
        if n == 0:
            return 1.0
        else:
            y = self.recur(x, n // 2) ** 2
            return y if n % 2 == 0 else y * x

但是这段代码不起作用并输出错误:

OverflowError: (34, 'Numerical result out of range')
  [Previous line repeated 19 more times]
    y = self.recur(x, n // 2) ** 2
Line 13 in recur (Solution.py)
    y = self.recur(x, n // 2) ** 2
Line 13 in recur (Solution.py)
    y = self.recur(x, n // 2) ** 2
Line 13 in recur (Solution.py)
    return 1.0 / self.recur(x, -n)
Line 7 in myPow (Solution.py)
    ret = Solution().myPow(param_1, param_2)
Line 40 in _driver (Solution.py)
    _driver()
Line 51 in <module> (Solution.py)

然后我尝试修改这些行:

            y = self.recur(x, n // 2) ** 2
            return y if n % 2 == 0 else y * x

            y = self.recur(x, n // 2) 
            return y*y if n % 2 == 0 else y *y* x

终于成功了。但为什么?它们之间的区别是什么?

添加失败案例:

x = 2.00000
n = -2147483648

有人能解答我的困惑吗?

python recursion pow
1个回答
4
投票

这是因为当结果不符合

inf
类型时,乘法返回
float
,而幂
**
抛出异常。例如,这会打印出
inf
:

r = 1.0
for _ in range(350):
    r = r * 10.0
print(r)

虽然这会引发 OverflowError:

print(10.0 ** 350)

PEP 中可能对此有一些解释,但我不知道。

正如评论中所指出的,您需要一个任意精度类型,而不是浮点数。考虑:

from decimal import Decimal

x = Decimal(10.0)
p = 350

r = Decimal(1.0)
for _ in range(350):
    r = r * x
print(r)

print(x ** 350)

这将正确打印结果。

© www.soinside.com 2019 - 2024. All rights reserved.