Le programme suivant est conçu pour calculer base^expo mod m
.Quel est le problème avec ma mise en œuvre itérative d'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))
En fait, je suis en train de convertir a tail-recursive program from SICP à son équivalent itératif. Voici le programme original:
(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))))
Le résultat de (expmod 42 1000000007 1000000007)
est 270001056, mais selon Fermat's Little Theorem, puisque 1000000007 est premier, le résultat devrait être 42.
Qu'est-ce que je fais mal?
Votre 'base' doit être au carré dans le cas-pair. En outre, BTW, Scheme fournit un prédicat "even?" Intégré et vous n'avez pas besoin de définir le vôtre. –
@ ChrisJester-Young Après que j'ai carré 'base' dans le cas-même, les choses semblent aller mal, même dans les cas les plus simples. Par exemple, '(expmod 3 5 8)' serait calculé à '1', alors que' 3^5 = 243 = 30 * 8 + 3' –
La fonction récursive originale est * non * récursive. – tfb