Как проверить, является ли число простым?
Как проверить, является ли число простым?
function IsPrime(N: Cardinal): Boolean; register;
// test if N is prime, do some small Strong Pseudo Prime test in certain bounds
// copyright (c) 2000 Hagen Reddmann, don't remove
asm
TEST EAX,1 { Odd(N) ?? }
JNZ @@1
CMP EAX,2 { N == 2 ?? }
SETE AL
RET
@@1: CMP EAX,73 { N JB @@C }
JE @@E { N == 73 ?? }
PUSH ESI
PUSH EDI
PUSH EBX
PUSH EBP
PUSH EAX { save N as Param for @@5 }
LEA EBP,[EAX - 1] { M == N -1, Exponent }
MOV ECX,32 { calc remaining Bits of M and shift M' }
MOV ESI,EBP
@@2: DEC ECX
SHL ESI,1
JNC @@2
PUSH ECX { save Bits as Param for @@5 }
PUSH ESI { save M' as Param for @@5 }
CMP EAX,08A8D7Fh { N = 9080191 ?? }
JAE @@3
// now if (N MOV EAX,31
CALL @@5 { 31^((N-1)(2^s)) mod N }
JC @@4
MOV EAX,73 { 73^((N-1)(2^s)) mod N }
PUSH OFFSET @@4
JMP @@5
// now if (N @@3: MOV EAX,2
CALL @@5
JC @@4
MOV EAX,7
CALL @@5
JC @@4
MOV EAX,61
CALL @@5
@@4: SETNC AL
ADD ESP,4 * 3
POP EBP
POP EBX
POP EDI
POP ESI
RET
// do a Strong Pseudo Prime Test
@@5: MOV EBX,[ESP + 12] { N on stack }
MOV ECX,[ESP + 8] { remaining Bits }
MOV ESI,[ESP + 4] { M' }
MOV EDI,EAX { T = b, temp. Base }
@@6: DEC ECX
MUL EAX
DIV EBX
MOV EAX,EDX
SHL ESI,1
JNC @@7
MUL EDI
DIV EBX
AND ESI,ESI
MOV EAX,EDX
@@7: JNZ @@6
CMP EAX,1 { b^((N -1)(2^s)) mod N == 1 mod N ?? }
JE @@A
@@8: CMP EAX,EBP { b^((N -1)(2^s)) mod N == -1 mod N ?? , EBP = N -1 }
JE @@A
DEC ECX { second part to 2^s }
JNG @@9
MUL EAX
DIV EBX
CMP EDX,1
MOV EAX,EDX
JNE @@8
@@9: STC
@@A: RET
@@B: DB 3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71
@@C: MOV EDX,OFFSET @@B
MOV ECX,18
@@D: CMP AL,[EDX + ECX]
JE @@E
DEC ECX
JNL @@D
@@E: SETE AL
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if IsPrime(3453451) then
ShowMessage('yes');
end;
{**** Another function ***}
function IsPrime(Prim: Longint): Boolean;
var
Z: Real;
Max: LongInt;
Divisor: LongInt;
begin
Prime := False;
if (Prim and 1) = 0 then Exit;
Z := Sqrt(Prim);
Max := Trunc(Z) + 1;
Divisor := 3;
while Max > Divisor do
begin
if (Prim mod Divisor) = 0 then Exit;
Inc(Divisor, 2);
if (Prim mod Divisor) = 0 then Exit;
Inc(Divisor, 4);
end;
Prime := True;
end;
Взято с сайта