微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python x** y与math.powx,y的指数

如何解决python x** y与math.powx,y的指数

使用Power运算符**将更快,因为它不会产生函数调用的开销。如果您反汇编Python代码,则可以看到以下内容

>>> dis.dis('7. ** i')
  1           0 LOAD_CONST               0 (7.0) 
              3 LOAD_NAME                0 (i) 
              6 BINARY_POWER         
              7 RETURN_VALUE         
>>> dis.dis('pow(7., i)')
  1           0 LOAD_NAME                0 (pow) 
              3 LOAD_CONST               0 (7.0) 
              6 LOAD_NAME                1 (i) 
              9 CALL_FUNCTION            2 (2 positional, 0 keyword pair) 
             12 RETURN_VALUE         
>>> dis.dis('math.pow(7, i)')
  1           0 LOAD_NAME                0 (math) 
              3 LOAD_ATTR                1 (pow) 
              6 LOAD_CONST               0 (7) 
              9 LOAD_NAME                2 (i) 
             12 CALL_FUNCTION            2 (2 positional, 0 keyword pair) 
             15 RETURN_VALUE

请注意,我在这里使用变量i作为指数,因为类似常数的表达式7. ** 5实际上是在编译时求值的。

现在,实际上,这种差异并不重要,正如您在计时时可以看到的那样:

>>> from timeit import timeit
>>> timeit('7. ** i', setup='i = 5')
0.2894785532627111
>>> timeit('pow(7., i)', setup='i = 5')
0.41218495570683444
>>> timeit('math.pow(7, i)', setup='import math; i = 5')
0.5655053168791255

所以,虽然powmath.pow大约慢一倍,但仍不够快,不会太在乎。除非您实际上可以将求幂识别为瓶颈,否则如果清晰度降低,就没有理由选择一种方法而不是另一种方法。这尤其适用,因为pow例如提供了集成的模运算。


Alfe在上述评论中提出了一个很好的问题:

timeit表明这math.pow**所有情况都要慢。math.pow()无论如何有什么好处?有谁知道它有什么好处呢?

math.pow内置函数pow和幂运算符的最大区别**在于,它 始终 使用浮点语义。因此,如果由于某种原因而要确保返回的结果是浮点数,math.pow则将确保此属性

我们来看一个示例:我们有两个数字ij,不知道它们是浮点数还是整数。但我们希望得到的浮点结果i^j。那么我们有什么选择呢?

  • 我们可以将至少一个参数转换为浮点数,然后执行i ** j
  • 我们可以i ** j将结果转换为浮点数(当浮点数为i或时,会自动使用浮点指数j,因此结果相同)。
  • 我们可以使用math.pow

因此,让我们测试一下:

>>> timeit('float(i) ** j', setup='i, j = 7, 5')
0.7610865891750791
>>> timeit('i ** float(j)', setup='i, j = 7, 5')
0.7930400942188385
>>> timeit('float(i ** j)', setup='i, j = 7, 5')
0.8946636625872202
>>> timeit('math.pow(i, j)', setup='import math; i, j = 7, 5')
0.5699394063529439

如您所见,math.pow实际上更快!如果考虑一下,函数调用的开销现在也消失了,因为在所有其他替代方案中,我们都必须调用float()


此外,可能值得指出的是**pow可以通过实现自定义类型的特殊__pow__(和__rpow__方法来覆盖和的行为。因此,如果您出于某种原因(无论出于何种原因)不希望使用它,math.pow则不会这样做。

解决方法

使用math.pow或**运算符哪个更有效?我什么时候应该使用另一个?

到目前为止,我知道x**y可以返回一个int或一个,float如果您使用小数,该函数pow将返回一个浮点数

import math

print math.pow(10,2)

print 10. ** 2

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。