Skip to content

Commit

Permalink
Improve prime-p
Browse files Browse the repository at this point in the history
  • Loading branch information
privet-kitty committed Nov 14, 2023
1 parent 63cd1b2 commit e2e88c2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 22 deletions.
44 changes: 22 additions & 22 deletions module/primality.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,32 @@ This module is tuned for SBCL on x86-64, i.e., (INTEGER 0
#.MOST-POSITIVE-FIXNUM) is assumed to be (UNSIGNED-BYTE 62)"))
(in-package :cp/primality)

;; NOTE: not sufficiently tested

(deftype uint () '(unsigned-byte 62))

(defun %strong-probable-prime-p (n base)
(declare (optimize (speed 3))
(uint n base))
(or (= n base)
(labels ((mod-power (base power)
(declare (uint base power))
(loop with res of-type uint = 1
while (> power 0)
when (oddp power)
do (setq res (mod (* res base) n))
do (setq base (mod (* base base) n)
power (ash power -1))
finally (return res))))
(let* ((d (floor (- n 1) (logand (- n 1) (- 1 n))))
(y (mod-power base d)))
(declare (uint y))
(or (= y 1)
(= y (- n 1))
(let ((s (tzcount (- n 1))))
(loop repeat (- s 1)
do (setq y (mod (* y y) n))
(when (<= y 1) (return nil))
(when (= y (- n 1)) (return t)))))))))
(labels ((mod-power (base power)
(declare (uint base power))
(loop with res of-type uint = 1
while (> power 0)
when (oddp power)
do (setq res (mod (* res base) n))
do (setq base (mod (* base base) n)
power (ash power -1))
finally (return res))))
(let* ((d (floor (- n 1) (logand (- n 1) (- 1 n))))
(y (mod-power base d)))
(declare (uint y))
(or (<= y 1)
(= y (- n 1))
(let ((s (tzcount (- n 1))))
(loop repeat (- s 1)
do (setq y (mod (* y y) n))
(when (<= y 1) (return nil))
(when (= y (- n 1)) (return t))))))))

;; https://primes.utm.edu/prove/prove2_3.html
;; https://miller-rabin.appspot.com/
Expand All @@ -42,8 +43,7 @@ This module is tuned for SBCL on x86-64, i.e., (INTEGER 0
(cond ((<= n 1) nil)
((evenp n) (= n 2))
((< n 49141)
(or (= n 331)
(%strong-probable-prime-p n 921211727)))
(%strong-probable-prime-p n 921211727))
((< n 4759123141)
(loop for base in '(2 7 61)
always (%strong-probable-prime-p n base)))
Expand Down
3 changes: 3 additions & 0 deletions module/test/primality.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@
(assert (eq (if (prime-p x) 1 0) (aref table x)))))
(loop repeat 5000
for x = (+ 4759123141 (* 2 (random 10000000 state)))
do (is (eq (prime-p x) (sb-int:positive-primep x))))
(loop repeat 5000
for x = (+ 2152302898747 (* 2 (random 10000000 state)))
do (is (eq (prime-p x) (sb-int:positive-primep x))))))

0 comments on commit e2e88c2

Please sign in to comment.