mirror of
https://github.com/PDP-10/its.git
synced 2026-01-19 01:27:05 +00:00
47 lines
1.5 KiB
Plaintext
47 lines
1.5 KiB
Plaintext
(cgol)$
|
|
|
|
% Rabin's probabilistic primality tester. The value of prime(n) (for LISP
|
|
users, say (PRIME N)) will be T or NIL, with a mistake on the average at most
|
|
prime_error_rate proportion of uses, assuming the random number generator has
|
|
no unfortunate properties. A composite may be mistaken for a prime, but not
|
|
vice versa. %
|
|
|
|
% commented out by ejs: 2018-10-01 since it appears to not work %
|
|
% export prime, witness_count, rab $ %
|
|
% The only symbols users of the package may access %
|
|
|
|
special n, n_1, witness_count, w, sw $
|
|
|
|
witness_count := 15; w := 2**35; sw:=w-1 $
|
|
|
|
define brnd(x); % Auxiliary routine for computing big random numbers%
|
|
if bigp x then random(sw) + w*brnd(x/:w) else random(x) $
|
|
|
|
define witness(); (brnd(n-2) rem (n-2)) + 2 $
|
|
|
|
define mexpt(a,j); % modular exponentiation %
|
|
if j=0 then 1
|
|
else if oddp j then (a*mexpt(a,j-1)) rem n
|
|
else mexpt(a,j/:2)**2 rem n $
|
|
|
|
define rab(a,j); % careful exponentiation - %
|
|
if oddp j then mexpt(a,j) % checks for Carmichaels %
|
|
else let x = rab(a,j/:2);
|
|
if x<2 then x
|
|
else if x = n_1 then 1
|
|
else let y = x**2 rem n; if y=1 then 0 else y $
|
|
|
|
'rbp' of 'prime' := 10 $
|
|
|
|
define "PRIME"(n); % Returns T if n is prime %
|
|
if n<30 then if n isin !'(2 3 5 7 11 13 17 19 23 29) then t else nil
|
|
else
|
|
gcd(n,6469693230) = 1
|
|
and
|
|
let n_1 = n-1;
|
|
iter for k := 1 step k+1
|
|
for looks_prime := (rab(witness(),n_1) = 1) step ditto
|
|
while looks_prime and k<witness_count
|
|
return looks_prime $
|
|
|
|
=EXIT$ |