一个应用非常普遍的素数检测算法:
我的实现:
(defun expmod (base exp modulo)
(if (= exp 0)
1
(if (evenp exp)
(mod (expt (expmod base (/ exp 2) modulo) 2) modulo)
(mod (* base (expmod base (- exp 1) modulo)) modulo))))
(defun initial (N)
(let ((s 0)(n (- N 1)))
(loop while (= (mod n 2) 0) do
(incf s)
(setf n (/ n 2)))
(list n s)))
(defun Rabin-Miller-once (n)
(let ((a (+ 1 (random n)))
(d (first (initial n)))
(s (second (initial n)))
(flag nil))
(if (= a n) (setf a (- a 1)))
(if (= 1 (expmod a d n))
(setf flag T)
(loop for k from 2 do
(setf d (* 2 d))
(if (or (= (- n 1) (expmod a d n)) (= 1 (expmod a d n)))
(progn (setf flag (not flag)) (return))
(if (> k s)
(return)))))
flag))
(defun Rabin-Miller (n c)
(let ((a nil))
(dotimes (i c)
(if (not (Rabin-Miller-once n))
(progn (setf a (not a)) (return))))
(not a)))