今天在做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
有人能解答我的困惑吗?
这是因为当结果不符合
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)
这将正确打印结果。