@Secure:
sorry aber
Delphi-Quellcode:
function IstPrim(const n:integer):boolean;
var x:integer;
begin
// Sonderfall 1 beachten
if (n = 1) then begin
result:=false;
exit;
end;
// Deine Primzahlprüfung hab' ich nicht ganz verstanden. Warum prüfst du nur die Teiler
// bis Round(N / 2)? Normalerweise prüft man doch von 2 bis Sqrt(N)!
result:=true;
for x:=2 to Trunc(Sqrt(N)) do
if ((n mod x) = 0) then begin
result:=false;
exit;
end;
end;
halte ich fr ziemlich übel.
1.) Du vereinfachst durch eigene Annahmen die gewünschte Funktionsweise des Programmieres, indem du enifach mal davon ausgehst das man eh nur Zahlen bis 2^31 testen möchte, statt eben wie im Original mit Int64 zu rechnen. Das ist wohl sehr schlechter Stil. Die Aufgabe des programmieres ist es die Forderungen EXAKT umzusetzen.
2.) dein Source ist fehlerhaft. Was ist mit 0, oder -1 oder allen Zahlen bis -(2^31-1). Übergibt man deiner Funktion einen Integer im Wertebereich der Integer von -2^31 bis 2^31 dann macht sie defacto exakt 50% Fehlerhafte Ausagen.
3.) dein Schreibstil, hm naja. Das Besondere in PASCAL ist es das man Gorß/Klein Schreibung als Mittel zu besseren Lesbarkeit einsetzen kann. Du verzichtest darauf indem du alles klein schreibst. Damit verzichtest du auf Übersichtlickeit.
4.) N. Wirth hat mit Absicht die "Gültigkeit eines Source Blocks" visuell grafisch auch als eingerückter Block mit einem senkrecht untereinander stehendem BEGIN und END eingeführt. Es ist also essentiell das BEGIN und END auf gleicher Einrückungsebene zu schreiben.
5.) was nun ? IstPrim() oder IsPrime() ? aber nicht IsPrim() das ist denglish.
6.) in der Mathemtik ist es üblich N als Synonym für eine Natürlich Zahl zu betrachten, so wie R für rationelle Zahlen etc.pp.
7.) Sonderfall 1 ist zu wenig und berücksicht eben nicht negative Zahlen
8.) die Berechnung in for X := 0 to Trunc(Sqrt(n)) ist zwar auf Grund des Delphi Compilers möglich sollte aber aus Sicht eines Standard PASCAL Codes vermieden werden. Unter Umständen, bei erweiterte PASCAL Dialekten mit einer for i to x step y Syntax ist nämlich x als Schleifenendebedingung dynamisch veränderbar.
9.) wenn es geht sollte man immer auf unnötige Sprachkonstruke verzichten und statt dessen mit "mathematischen" Zuweisungen arbeiten.
10.) wenn es geht exit/goto/continue vermeinden
11.) man muß nur mit ungeraden Zahlen die Trialdivision durchführen. Da es aber in Delphi keine for i tox step y Schleife gibt müsste man sich behelfen mit for x := 2 to Trunc(Sqrt(N)) div 2 do und mit if N mod (i*2+1) = 0 arrbeiten, um eben den offensichtlichen mathematischen Erfordernissen gerecht zu werden. Es geht hier um Exaktheit in der Programmier Arbeit die man leistet. Allerdings ist eine solche Zähleschleife wesentlich schlechter zu verstehen als eine while Schleife. In deinem Falle testet deine Funktion die Zahl N doppelt so häufig als es nötig wäre, ergo Effizienzeinbußen.
Delphi-Quellcode:
function IsPrime(const N: Int64): Boolean;
var
Root,Candidate: Int64;
begin
Result := Odd(N) and (N > 2); // Eine Primzahl ist ungerade und größer 1, ausser der 2
if Result then
begin
// da wir N als Int64 vorgegeben haben können wir NICHT per Zählschleifen arbeiten, Delphi unterstützt
// keine Int64 als Schleifenzähler, ergo while schleife
Root := Trunc(Sqrt(N));
Candidate := 3;
while Result and (Candidate < Root) do
begin
Result := N mod Candidate <> 0; // statt IF THEN eine mathematische, boolsche Zuweisung
Candidate := Candidate + 2;
end;
end else
Result := N = 2; // den einzigsten Fall einer geraden Primzahl berücksichtigen
// statt IF THEN eine boolsche Zuweisung
end;