快速幂

问题:求一个非负数的n次方。数学表达,

其中, 叫底数, 叫次数, 成为 次幂。当 时,有 . 特别的,约定 .

现在要设计一个算法,求解 .

; recursive
(define (expo b n)
	(if (= n 0)
        1
        (* b (expo b (- n 1)))))
 
; iterative
(define (expon b n)
	(define (exp-iter prod cnt)
		(if (= cnt n)
            prod
            (exp-iter (* b prod) (+ cnt 1))))
    (exp-iter 1 0))
 
;; test
(expo 3 4)
(expon 3 4)
 
;; a fast version
(define (fast-exp b n)
	(cond ((= n 0) 1)
          ((even? n)
           (square (fast-exp b (/ n 2))))
          (else (* b (fast-exp b (- n 1))))))
 
;; test
(fast-exp 3 4)
// 快速幂,可能会溢出
unsigned long long exp(unsigned b, unsigned n) {
	unsigned long long ans = 1;
	while (n > 0) {
		if (n & 1) { // 指数为奇数,先乘一次底数
			ans *= b;
		}
		b *= b;  // 底数自乘,指数折半
		n >>= 1; // 指数除2
	}
	return ans;
}

有些知识点,很小,也不难。但要用的时候,总是记不全,所以有被记录的价值。