Следующая программа предназначена для расчета base^expo mod m
.Что случилось с моей итеративной реализацией expmod?
(define (expmod base expo m)
(define (square n)
(* n n))
(define (even? n)
(= (remainder n 2) 0))
(define (expmod-iter base expo m result)
(cond ((= expo 0) result)
((even? expo)
(expmod-iter base
(/ expo 2)
m
(remainder (square result) m)))
(else
(expmod-iter base
(- expo 1)
m
(remainder (* base result) m)))))
(expmod-iter base expo m 1))
На самом деле, я пытаюсь преобразовать a tail-recursive program from SICP его итерационного эквивалент. Вот оригинальная программа:
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(remainder (square (expmod base (/ exp 2) m))
m))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
Результат (expmod 42 1000000007 1000000007)
является 270001056, но, по словам Fermat's Little Theorem, так как 1000000007 первична, результат должен быть 42.
Что я делаю неправильно?
Ваша «база» должна быть квадратной в четном случае. Кроме того, BTW, Scheme предоставляет встроенный предикат 'even? ', И вам не нужно определять свои собственные. –
@ ChrisJester-Young После того, как я построил «базу» в четном случае, все кажется неправильным даже в самых простых случаях. Например, '(expmod 3 5 8)' будет вычисляться до '1', тогда как' 3^5 = 243 = 30 * 8 + 3' –
Исходная рекурсивная функция * не * хвостовая рекурсивная. – tfb