【问题标题】:OverflowError: (34, 'Numerical result out of range') in writing a custom implementation of pow(x,n)OverflowError: (34, 'Numerical result out of range') 在编写 pow(x,n) 的自定义实现
【发布时间】:2019-05-07 20:14:06
【问题描述】:

在实现 pow(x, n), for (x=2,and n=-2147483648) 时,我收到以下错误:

代码:

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 如下代码 sn-p 时,我得到 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解释器不处理尾递归优化,并且返回的结果被保留,因为它稍后用于进一步计算。

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

【问题讨论】:

  • 我认为错误不是由于 stackoverflow 而是由于 int 数据类型容纳大量数字的能力。
  • 您忘记实现基本案例。当 n == 1 或 0 时会发生什么?
  • n/2 或赋值不太可能出错。您确定这是您的实际代码吗?我觉得这里少了点什么。也许我错过了什么?
  • @MadPhysicist 请注意,OP 正在递归调用内置的 pow 而不是 myPow - 可能是一个错字,但仍值得调查以供将来参考

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


【解决方案1】:

/ 在 Python 3.x 中总是执行 浮点 除法,这与在 Python 2.x 中必须显式转换操作数不同。因此type(n/2) == floattype(int(n/2)) == int。或者,您可以使用n // 2 // 执行地板/整数除法。

如果任一参数也是floats,则内置pow 函数将返回float。在内部,这些是双精度浮点数,可以 store up to ~10308 - 远小于 22147483648/2,因此是 OverflowError

【讨论】:

    【解决方案2】:

    计算后返回值的大小太大,即使对于浮点变量也无法存储,因此会出现 OverFlowError 异常

    【讨论】:

    • 当我将幂类型转换为 int(在这种情况下不会丢失精度)时,不会发生异常。
    猜你喜欢
    • 1970-01-01
    • 2014-10-23
    • 2021-04-26
    • 2017-03-31
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 2013-04-27
    相关资源
    最近更新 更多