如何在Python中实现取幂?

时间:2012-09-11 20:45:15

标签: python

我能够使用Binet的公式计算任何正常可计算的fibonnaci数(除非结果变得很大),使用Binet公式,即用于计算fibonnaci数的闭合公式。这是我的代码:

用于非递归实施fibonnaci:

gr = (1 + 5**0.5) / 2
def gfib(n):
    return int(((gr**n - (1-gr)**n) / 5**0.5))

我理解^ ^ n表示指数运行时复杂度,但是当代码在python中运行时不是这种情况,因为这会立即计算第n个fibonnaci数。我已经做了一些关于如何在python中实现指数的研究(可能是通过平方取幂?)来给出我得到的恒定时间解,但是还没有找到明确的答案。有什么想法吗?

3 个答案:

答案 0 :(得分:12)

float.__pow__()方法使用C libm,它充分利用了对二进制浮点运算的硬件支持。后者使用对数表示数字。对数表示使得实现指数成为可能只需一次乘法。

执行摘要:浮动指数在硬件中实现,并且由于对数的魔力而以几乎恒定的速度运行。

答案 1 :(得分:9)

整数的指数可以比你想象的更有效地计算。这是Wikipedia has to say about it

  

计算bⁿ的最简单方法需要n-1个乘法运算,但可以比它更有效地计算,如下例所示。要计算2¹⁰⁰,请注意100 = 64 + 32 + 4.按顺序计算以下内容:

2² = 4
(2²)² = 2⁴ = 16
(2⁴)² = 2⁸ = 256
(2⁸)² = 2¹⁶ = 65,536
(2¹⁶)² = 2³² = 4,294,967,296
(2³²)² = 2⁶⁴ = 18,446,744,073,709,551,616
2⁶⁴ × 2³² × 2⁴ = 2¹⁰⁰ = 1,267,650,600,228,229,401,496,703,205,376
  

这一系列步骤只需要8次乘法操作而不是99次(因为上面的最后一个产品需要2次乘法)。

     

通常,使用exponentiation by squaring 或(更一般地)addition-chain exponentiation,计算bⁿ所需的乘法运算的数量可以减少到Θ(log n)。找到bⁿ的最小乘法序列(指数的最小长度加法链)是一个难以解决的问题,目前还没有有效的算法(参见子集和问题),但是有许多合理有效的启发式算法可供使用。[29]

通过平方指数的页面很难总结,但它基本上是2⁸==(2⁴)²==(2²)²)²的想法,所以不用计算2 × 2 × 2 × 2 × 2 × 2 × 2 × 2 = 256,你可以计算{ {1}}。

答案 2 :(得分:5)

您可以在CPython的source code for the log_pow function找到实现。