3
我是Scheme的新手。我嘗試並使用PLT方案實施Rabin-Miller算法的概率變體。我知道這是隨機的,但大部分時間我都會得到錯誤的結果。我用C實現了相同的功能,並且它運行良好(從未嘗試失敗)。我在調試時得到了預期的輸出,但是當我運行時,它幾乎總是返回錯誤的結果。我使用了Wikipedia的算法。Miller-Rabin Scheme實現不可預知的輸出
(define expmod(lambda(b e m)
;(define result 1)
(define r 1)
(let loop()
(if (bitwise-and e 1)
(set! r (remainder (* r b) m)))
(set! e (arithmetic-shift e -1))
(set! b (remainder (* b b) m))
(if (> e 0)
(loop)))r))
(define rab_mil(lambda(n k)
(call/cc (lambda(breakout)
(define s 0)
(define d 0)
(define a 0)
(define n1 (- n 1))
(define x 0)
(let loop((count 0))
(if (=(remainder n1 2) 0)
(begin
(set! count (+ count 1))
(set! s count)
(set! n1 (/ n1 2))
(loop count))
(set! d n1)))
(let loop((count k))
(set! a (random (- n 3)))
(set! a (+ a 2))
(set! x (expmod a d n))
(set! count (- count 1))
(if (or (= x 1) (= x (- n 1)))
(begin
(if (> count 0)(loop count))))
(let innerloop((r 0))
(set! r (+ r 1))
(if (< r (- s 1)) (innerloop r))
(set! x (expmod x 2 n))
(if (= x 1)
(begin
(breakout #f)))
(if (= x (- n 1))
(if (> count 0)(loop count)))
)
(if (= x (- s 1))
(breakout #f))(if (> count 0) (loop count)))#t))))
另外,我的計劃是正確的方式嗎? (我不知道關於突破環路部分,我使用call/cc
,我發現它在一些網站,並從那以後一直使用它。)
在此先感謝。
您不需要調用/ cc來打破循環!回來。我會用較少的突變重寫rab,將變量作爲參數傳遞給循環而不是變異它們。 – 2010-02-10 11:41:48
謝謝查爾斯。但是,我如何退出循環?我無法使用「返回」關鍵字或任何等效的plt方案。 – user270207 2010-02-10 12:04:13
此代碼片段不是Scheme。它是類C語言的C語言。 – Svante 2010-02-10 20:08:42