IsPrime.pas 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. {IsPrime.Pas ver. 2.0 (c) Max Alekseyev <relf@os2.ru>, 2:5015/60@FidoNet}
  2. {Реализация вероятностного алгоритма Миллера-Рабина с 20 раундами.
  3. Для примера выдает простые на отрезке [1000000000,1000100000].
  4. Вероятность ошибки (то, что составное число будет названо простым) меньше
  5. 4^(-Rounds).}
  6. const Rounds=20;
  7. function mulmod(x,y,m:longint):longint; assembler;
  8. asm
  9. {$IFDEF USE32}
  10. mov eax,x
  11. mul y
  12. div m
  13. mov eax,edx
  14. {$ELSE}
  15. db $66; mov ax,word ptr x
  16. db $66; mul word ptr y
  17. db $66; div word ptr m
  18. mov ax,dx
  19. db $66; shr dx,16
  20. {$ENDIF}
  21. end;
  22. function powmod(x,a,m:longint):longint;
  23. var r:longint;
  24. begin
  25. r:=1;
  26. while a>0 do
  27. begin
  28. if odd(a) then r:=mulmod(r,x,m);
  29. a:=a shr 1;
  30. x:=mulmod(x,x,m);
  31. end;
  32. powmod:=r;
  33. end;
  34. function isprime(p:longint):boolean;
  35. var q,i,a:longint;
  36. begin
  37. if odd(p) and (p>1) then
  38. begin
  39. isprime:=true;
  40. q:=p-1;
  41. repeat q:=q shr 1; until odd(q);
  42. for i:=1 to Rounds do
  43. begin
  44. {$IFDEF USE32} a:=Random(p-2)+2; {$ELSE} a:=2+Trunc(Random*(p-2)); {$ENDIF}
  45. if powmod(a,p-1,p)<>1 then
  46. begin
  47. isprime:=false; break;
  48. end;
  49. a:=powmod(a,q,p);
  50. if a<>1 then
  51. begin
  52. while (a<>1) and (a<>p-1) do a:=mulmod(a,a,p);
  53. if a=1 then
  54. begin
  55. isprime:=false; break;
  56. end;
  57. end;
  58. end;
  59. end else isprime:=(p=2);
  60. end;
  61. var t:longint;
  62. begin
  63. Randomize; {Do not forget to reset Random Generator!}
  64. for t:=1000000000 to 1000100000 do if isprime(t) then writeln(t);
  65. end.