A Kis-Fermat-tétel szerint p|a^p-a, minden p prímre és a egészre. Az viszont nem igaz, hogy ha az oszthatóság teljesül, akkor p prím. (Épp ezért a Kis-Fermat-tétellell csak ,,valószínűségi'' alapon tudjuk eldönteni egy számról, hogy prím-e.) Azokat a számokat, melyekre teljesül az oszthatóság minden a-ra, de összetettek, álprímeknek nevezzük. Ezen az oldalon az álprímkereséssel foglalkozunk.
Az első néhány álprím: 561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341, 41041, 46657, 52633, 62745, 63973, 75361, 101101, 115921, 126217, 162401, 172081, 188461, 252601, 278545, 294409, 314821, 334153, 340561, 399001, 410041, 449065, 488881, 512461, 530881, 552721, 656601, 658801, 670033, 748657, 825265, 838201, 852841, 997633, 1024651, 1033669, 1050985, 1082809. Mint látható, az álprímek igen ritkák. Ahhoz, hogy egy ilyen listát elkészítsünk, az alábbihoz hasonló programot kell futtatni napestig:
#include <stdio.h> #include <string.h> #include <stdlib.h> #if 0 #define num unsigned int #define nump "%d" #endif #if 0 #define num unsigned long #define nump "%ld" #endif #if 1 #define num unsigned long long #define nump "%Ld" #endif num hatvanyoz(num x, num n, num m) { /* by Knuth */ num y, z; int b; y=1; if (m<2 || !x) { y=0; } else if (x!=1) { z=x%m; while (1) { b=n&1; n>>=1; if (b) { y*=z; if (y>=m) y%=m; if (!n) break; } z*=z; if (z>=m) z%=m; } } return y; } int prim_e(num l) { num d=5, s=5; if (l<=7) return (l!=4 && l!=6); if (!(l&1) || !(l%3)) return 0; while (s<=l) { if (!(l%d)) return 0; s+=4+(d<<2); d+=2; if (s>l) break; if (!(l%d)) return 0; s+=16+(d<<3); d+=4; } return 1; } num lnko(num a, num b) { /* 0,0-ra rossz */ num r; while (1) { if (!a) return b; if (!b) return a; if (a==1 || b==1) return 1; r=b%a; b=a; a=r; } } int pprim_e(num l) { num i, m; if (!(l&1)) return 0; for (i=2;i<l;i++) { if (lnko(i,l)!=1) continue; m=hatvanyoz(i,l-1,l); if (m!=1) return 0; } return 1; } char milyen(num l) { if (!pprim_e(l)) return '.'; if (prim_e(l)) return 'p'; return 's'; } /* prim pprim . 0 osszetett s 0 1 alprim p 1 1 prim */ int main(int argc, char **argv) { num i, debug=0; char c; if (argc<2) i=0; else if (argc==2) i=atol(argv[1]); else if (argc==3) { i=atol(argv[1]); debug=1; } if (debug) { while (1) { if ((c=milyen(i))=='s') printf(nump "\n", i); putc(c, stderr); i++; if (!(i&8191)) { fflush(stdout); fflush(stderr); } } } else { while (1) { if ((c=milyen(i))=='s') printf(nump "\n", i); i++; if (!(i&8191)) fflush(stdout); } } return 0; }
A programnak első paraméterként megadható, hogy honnan induljon a keresés. Ha második paramétert is kap, akkor a stderr-re számonként egy-egy byte-ot ('.', 's' vagy 'p') ír.
Ez a lap pts oldalai közül való.