Your message was blank, but I presume that you would like some
LISP code to find prime numbers. Below is some code that
does just that. It can find a 200-digit prime number in less
than 3 minutes on an RS/6000 in Allegro CL. I wrote it while
playing around with the RSA encryption algorithm in class
last semester. I'll place it in the public domain.
It can probably be optimized even further by adding more type declarations.
Note: finding a 200-digit prime number conses 95MB of garbage.
Call:
(find-prime 10)
To find a 10-digit prime number. You can easily modify the find-prime
function to test the primality of a given number.
Mike
(······@cs.utexas.edu)
;;; ********************************************************************
;;;
;;; prime.lisp - find prime numbers
;;;
;;; Micheal Hewett 11 October 1994
;;; University of Texas
;;; ······@cs
;;;
;;; Some info and algorithms are from "Elementary Number Theory and its
;;; Applications", Kenneth H. Rosen, Addison-Wesley, 1985.
;;;
;;; -------------------------------------------------
;;; Primality testing Functions
;;; -------------------------------------------------
(in-package 'user)
(defparameter *max-tests* 50
"How many times do you want to call Miller's test for primality?
A value of 100 gives virtual certainty. p is (1/4)^n")
(defun factor-out-twos (possible-prime)
"Returns two values: s and o, where ((o * 2^s) + 1)= possible-prime."
;;; Find odd factor 'o', such that (2^s)*o = possible-prime.
;;; This is 't' in Rosen's book (p. 156).
(let* ((o (1- possible-prime))
(s 0)
(next-o 0)
(remainder 0)
)
(loop
(multiple-value-setq
(next-o remainder)
(floor o 2))
(when (not (zerop remainder))
(return))
(incf s)
(setq o next-o)
)
(values s o) ;; Return values
)
)
(defun square (x) (* x x))
(defun expmod (base exponent modulus)
"Returns (b^e) mod m"
(declare (type integer base exponent modulus))
;;This is defined in Abelson & Sussman (1985).
(cond ((zerop exponent) 1)
((evenp exponent)
(rem (square (expmod base (/ exponent 2) modulus)) modulus))
(T (rem (* base (expmod base (- exponent 1) modulus)) modulus))
)
)
(defun millers-test (possible-prime base s o)
"Returns T if the prime passes Miller's test for the base.
S is the largest number such that ((2^s)*o + 1) = possible-prime."
(declare (type integer possible-prime base s o))
(let* ((pp-1 (1- possible-prime))
(mod-value (expmod base o possible-prime))
)
(declare (type integer pp-1 mod-value))
(or (= 1 mod-value) ;; Test: b^o = 1 mod p
(dotimes (j s NIL) ;;b^(o*2^j) = -1 mod p
(when (= pp-1 mod-value)
(return T))
(setq mod-value (mod (* mod-value mod-value)
possible-prime)) ; Test: b^(no) => b^(2no)
)
)
)
)
(defun find-prime (number-of-digits)
"Returns a prime number greater than 10^(n-1).
This functions uses Rabin's probabilistic primality test."
(do* ((p (1+ (expt 10 (1- number-of-digits))) (+ p 2))
(base 0)
(s 0)
(o 0)
)
(nil nil)
(multiple-value-setq
(s o)
(factor-out-twos p)
)
;; Check *max-tests* random bases smaller than the prime.
;; If it passes Miller's test for 100 of them, it is almost
;; certainly a prime (p < 10^-60).
;;
(when
(dotimes (i *max-tests* T)
(setq base (random p))
(unless (millers-test p base s o)
(return NIL))
)
(return p)
)
)
)