为何实现pow(x,n)的第一段代码数值溢出,第二段正常?
问题
实现计算pow(x,n)的函数时,输入参数为(x=2.00000, n=-2147483648)时,第一段代码触发Numerical result out of range错误,第二段代码却能正常运行,请问原因是什么?
出错代码
class Solution: def myPow(self, x: float, n: int) -> float: if n>=0: return self.powpositive(x,n) else: return 1/self.powpositive(x,-n) def powpositive(self,x,n): if n==0: return 1 else: if n%2==0: return pow(self.powpositive(x,n//2),2) else: return x*pow(self.powpositive(x,(n-1)//2),2)
错误信息
OverflowError: (34, 'Numerical result out of range') [Previous line repeated 19 more times] return pow(self.powpositive(x,n//2),2) Line 15 in powpositive (Solution.py) return pow(self.powpositive(x,n//2),2) Line 15 in powpositive (Solution.py) return pow(self.powpositive(x,n//2),2) Line 15 in powpositive (Solution.py) return 1/self.powpositive(x,-n) Line 6 in myPow (Solution.py) ret = Solution().myPow(param_1, param_2) Line 46 in _driver (Solution.py) _driver() Line 57 in <module> (Solution.py)
正常运行的代码
class Solution: def myPow(self, x: float, n: int) -> float: if n>=0: return self.powpositive(x,n) else: return 1/self.powpositive(x,-n) def powpositive(self,x,n): if n==0: return 1 elif n==1: return x else: ret=self.powpositive(x,n//2) if n%2==0: return ret*ret else: return x*ret*ret
原因分析
两段代码的核心差异在于平方计算的实现方式:
- 出错代码使用Python内置的
pow(a,2)求平方,而正常代码直接用ret*ret完成平方运算。 - 当计算
2^2147483648时,这个数值远超Python浮点数的最大可表示范围(约1.8e308)。 - 内置
pow函数遇到这种超大数平方会直接抛出OverflowError;而用ret*ret的话,浮点数溢出后会自动转为inf(无穷大),后续计算1/inf会得到合法的0.0,不会触发错误。
顺带提一句,正常代码里的n==1终止条件只是优化了递归深度,不是导致错误的关键因素,核心还是平方计算的方式不同。
内容的提问来源于stack exchange,提问作者Jxb
相关产品推荐
相关产品推荐

