Skip to content Skip to footer

平方求幂

通过2的幂进行计算

编辑

这是用Ruby写的上述算法的非递归实现。

由于低级语言会将 n=n/2 隐式向0取整,n=n-1 对那些语言来说,就是冗余的步骤了。

n[0]是n的二进制表示的最右边的位,所以如果它是1,则该数是奇数,如果它是零,则该数是偶数。它也是以2为模n的余数。

def power(x,n)

result = 1

while n.nonzero?

if n[0].nonzero?

result *= x

n -= 1

end

x *= x

n /= 2

end

return result

end

运行实例:计算 310

编辑

parameter x = 3

parameter n = 10

result := 1

Iteration 1

n = 10 -> n is even

x := x2 = 32 = 9

n := n / 2 = 5

Iteration 2

n = 5 -> n is odd

-> result := result * x = 1 * x = 1 * 32 = 9

n := n - 1 = 4

x := x2 = 92 = 34 = 81

n := n / 2 = 2

Iteration 3

n = 2 -> n is even

x := x2 = 812 = 38 = 6561

n := n / 2 = 1

Iteration 4

n = 1 -> n is odd

-> result := result * x = 32 * 38 = 310 = 9 * 6561 = 59049

n := n - 1 = 0

return result

运行实例:计算 310

编辑

result := 3

bin := "1010"

Iteration for digit 2:

result := result2 = 32 = 9

1010bin - Digit equals "0"

Iteration for digit 3:

result := result2 = (32)2 = 34 = 81

1010bin - Digit equals "1" --> result := result*3 = (32)2*3 = 35 = 243

Iteration for digit 4:

result := result2 = ((32)2*3)2 = 310 = 59049

1010bin - Digit equals "0"

return result

JavaScript-Demonstration: http://home.mnet-online.de/wzwz.de/temp/ebs/en.htm (页面存档备份,存于互联网档案馆)

幂的乘积的计算

编辑

平方求幂也可用于计算2个或多个幂的乘积。

如果基础群或半群是可交换的,那么常常可以通过同时计算乘积来减少乘法的次数。

例子

编辑

式子 a7×b5 可以分三步计算:

((a)2×a)2×a (计算 a7 需要四次乘法)

((b)2)2×b (计算 b5 需要三次乘法)

(a7)×(b5) (计算二者乘积需要一次乘法)

所以总共需要八次乘法。

更快的解法是同时计算这两个幂

((a×b)2×a)2×a×b

总共只需要6次乘法。注意 a×b 计算了两次;结果可以在第一次计算后存储,这将乘法计数减少到5次。

有数字的例子:

27×35 = ((2×3)2×2)2×2×3 = (62×2)2×6 = 722×6 = 31,104

如果至少有两个指数大于1的话,同时计算幂就会比单独计算减少乘法次数。

使用变换

编辑

如果表达式在计算前进行变换,上面的例子 a7×b5 也可以只用5次乘法就计算出来:

a7×b5 = a2×(ab)5 其中 ab := a×b

ab := a×b(一次乘法)

a2×(ab)5 = ((ab)2×a)2×ab(四次乘法)

这个变换可以推广成下面的方案:

对于计算 aA×bB×...×mM×nN

首先:定义 ab := a×b, abc = ab×c, ...

然后:计算变换后的表达式 aA−B×abB−C×...×abc..mM−N×abc..mnN

在计算之前进行变换通常会减少乘法计数,但在某些情况下也会增加计数(请参见下面最后一个示例),因此在使用变换后的表达式进行计算之前,最好检查一下乘法的次数。

例子

编辑

对于下面的表达式,表中显示了分开计算每个幂,在不进行变换的情况下同时进行计算,以及在变换后同时进行计算的乘法次数。

例子

a7×b5×c3

a5×b5×c3

a7×b4×c1

分开计算

[((a)2×a)2×a] × [((b)2)2×b] × [(c)2×c](11次乘法)

[((a)2)2×a] × [((b)2)2×b] × [(c)2×c](10次乘法)

[((a)2×a)2×a] × [((b)2)2] × [c](8次乘法)

同时计算

((a×b)2×a×c)2×a×b×c(8次乘法)

((a×b)2×c)2×a×b×c(7次乘法)

((a×b)2×a)2×a×c(6次乘法)

变换

a := 2 ab := a×b abc := ab×c(2次乘法)

a := 2 ab := a×b abc := ab×c(2次乘法)

a := 2 ab := a×b abc := ab×c(2次乘法)

之后的计算

(a×ab×abc)2×abc(4次乘法 ⇒ 总共6次)

(ab×abc)2×abc(3次乘法 ⇒ 总共5次)

(a×ab)2×a×ab×abc(5次乘法 ⇒ 总共7次)

Copyright © 2088 我的世界杯_瑞奇马丁世界杯主题曲 - msdc8.com All Rights Reserved.
友情链接