Python ** operator vs math.pow

来源:互联网 发布:2018年考研人数 知乎 编辑:程序博客网 时间:2024/06/06 02:22
math.pow(xy)

Return x raised to the power y. Exceptional cases follow Annex ‘F’ of the C99 standard as far as possible. In particular, pow(1.0, x) and pow(x, 0.0) always return 1.0, even when x is a zero or a NaN. If both x and y are finite,x is negative, and y is not an integer then pow(x, y) is undefined, and raises ValueError.

Unlike the built-in ** operator, math.pow() converts both its arguments to type float.

 Use ** or the built-in pow()function for computing exact integer powers.

Changed in version 2.6: The outcome of 1**nan and nan**0 was undefined.

math.sqrt(x)

Return the square root of x.



** operator v.s. math.pow

不知道有沒有注意過, Python 裡面有 ** operator 可以做指數運算, 而 math.pow 也可以做指數運算, 到底差在哪裡? 甚至有時候 ** operator 會比較快,為什麼?

主要的差別在於 math.pow 會把傳入的兩個參數都先轉成 float , 可以保證回傳的一定是 float, ** 則不一定 (甚至可以做虛數次方的運算)。 另外一個點是 ** 的行為可以根據 __pow__ 和 __rpow__ 來改變, 而 math.pow 則不會, 如果不想使用到 __pow__ 或 __rpow__ 的東西的話, 可以指定使用 math.pow 。

寫一段小程式測試:

from dis import disfrom timeit import timeitoperations = ( ('2 ** 42', ''),            ('pow(2, 42)', ''),            ('math.pow(2, 42)', 'import math'),            ('2 ** i', 'i = 42'),            ('pow(2, i)', 'i = 42'),            ('math.pow(2, i)', 'import math; i = 42'),            ('i ** j', 'i, j = 2, 42'),            ('pow(i, j)', 'i, j = 2, 42'),            ('math.pow(i, j)', 'import math; i, j = 2, 42'), )result = []for operation in operations:    expr, setup = operation    time = timeit(expr, setup=setup)    result.append('{:16}: {:<21} s'.format(expr, time))print('\n'.join(result))for operation in operations:    expr, _ = operation    print('\n{} :\n'.format(expr))    dis(expr)

Python 3.4 :

2 ** 42         : 0.02503299992531538   spow(2, 42)      : 0.5010730230715126    smath.pow(2, 42) : 0.4331468460150063    s2 ** i          : 0.3975521819666028    spow(2, i)       : 0.5939885310363024    smath.pow(2, i)  : 0.2997760840225965    si ** j          : 0.48525534803047776   spow(i, j)       : 0.5479897629702464    smath.pow(i, j)  : 0.2728949940064922    s2 ** 42 :1           0 LOAD_CONST               2 (4398046511104)            3 RETURN_VALUEpow(2, 42) :1           0 LOAD_NAME                0 (pow)            3 LOAD_CONST               0 (2)            6 LOAD_CONST               1 (42)            9 CALL_FUNCTION            2 (2 positional, 0 keyword pair)            12 RETURN_VALUEmath.pow(2, 42) :1           0 LOAD_NAME                0 (math)            3 LOAD_ATTR                1 (pow)            6 LOAD_CONST               0 (2)            9 LOAD_CONST               1 (42)            12 CALL_FUNCTION            2 (2 positional, 0 keyword pair)            15 RETURN_VALUE2 ** i :1           0 LOAD_CONST               0 (2)            3 LOAD_NAME                0 (i)            6 BINARY_POWER            7 RETURN_VALUEpow(2, i) :1           0 LOAD_NAME                0 (pow)            3 LOAD_CONST               0 (2)            6 LOAD_NAME                1 (i)            9 CALL_FUNCTION            2 (2 positional, 0 keyword pair)            12 RETURN_VALUEmath.pow(2, i) :1           0 LOAD_NAME                0 (math)            3 LOAD_ATTR                1 (pow)            6 LOAD_CONST               0 (2)            9 LOAD_NAME                2 (i)            12 CALL_FUNCTION            2 (2 positional, 0 keyword pair)            15 RETURN_VALUEi ** j :1           0 LOAD_NAME                0 (i)            3 LOAD_NAME                1 (j)            6 BINARY_POWER            7 RETURN_VALUEpow(i, j) :1           0 LOAD_NAME                0 (pow)            3 LOAD_NAME                1 (i)            6 LOAD_NAME                2 (j)            9 CALL_FUNCTION            2 (2 positional, 0 keyword pair)            12 RETURN_VALUEmath.pow(i, j) :1           0 LOAD_NAME                0 (math)            3 LOAD_ATTR                1 (pow)            6 LOAD_NAME                2 (i)            9 LOAD_NAME                3 (j)            12 CALL_FUNCTION            2 (2 positional, 0 keyword pair)            15 RETURN_VALUE

PyPy3 (PyPy 2.4.0, Python 3.2.5)

2 ** 42         : 0.0019397735595703125 spow(2, 42)      : 0.002593994140625     smath.pow(2, 42) : 0.07702302932739258   s2 ** i          : 0.03540802001953125   spow(2, i)       : 0.03392314910888672   smath.pow(2, i)  : 0.07650113105773926   si ** j          : 0.03323793411254883   spow(i, j)       : 0.03371095657348633   smath.pow(i, j)  : 0.07712817192077637   s2 ** 42 :1           0 LOAD_CONST               0 (4398046511104)            3 RETURN_VALUEpow(2, 42) :1           0 LOAD_NAME                0 (pow)            3 LOAD_CONST               0 (2)            6 LOAD_CONST               1 (42)            9 CALL_FUNCTION            2            12 RETURN_VALUEmath.pow(2, 42) :1           0 LOAD_NAME                0 (math)            3 LOOKUP_METHOD            1 (pow)            6 LOAD_CONST               0 (2)            9 LOAD_CONST               1 (42)            12 CALL_METHOD              2            15 RETURN_VALUE2 ** i :1           0 LOAD_CONST               0 (2)            3 LOAD_NAME                0 (i)            6 BINARY_POWER            7 RETURN_VALUEpow(2, i) :1           0 LOAD_NAME                0 (pow)            3 LOAD_CONST               0 (2)            6 LOAD_NAME                1 (i)            9 CALL_FUNCTION            2            12 RETURN_VALUEmath.pow(2, i) :1           0 LOAD_NAME                0 (math)            3 LOOKUP_METHOD            1 (pow)            6 LOAD_CONST               0 (2)            9 LOAD_NAME                2 (i)            12 CALL_METHOD              2            15 RETURN_VALUEi ** j :1           0 LOAD_NAME                0 (i)            3 LOAD_NAME                1 (j)            6 BINARY_POWER            7 RETURN_VALUEpow(i, j) :1           0 LOAD_NAME                0 (pow)            3 LOAD_NAME                1 (i)            6 LOAD_NAME                2 (j)            9 CALL_FUNCTION            2            12 RETURN_VALUEmath.pow(i, j) :1           0 LOAD_NAME                0 (math)            3 LOOKUP_METHOD            1 (pow)            6 LOAD_NAME                2 (i)            9 LOAD_NAME                3 (j)            12 CALL_METHOD              2            15 RETURN_VALUE

Reference

  • Exponentials in python x.**y vs math.pow(x, y)

  • Why is 2**100 so much faster than math.pow(2,100)?

  • Python - math - Mathematical functions
    • This module is always available. It provides access to the mathematical functions defined by the C standard.

0 0
原创粉丝点击