Zitat:
Zitat von
negaH:
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.
Ich finde, dass sich der Quelltext dadurch nur um eine weitere Zeile aufbläht. Logisch ist die genaue Einteilung mit begin/end ohnehin für Menschen nicht (IMO): Schließlich ist es ja egal, wie viele Anweisungen danach folgen (nach einer if-Bedingung zB), es muss nur dem Compiler genau gesagt werden.
Und genau das ist die falsche Sichtweise. Du versuchst die Anzahl an Zeilen zu optimieren statt sich darauf zu konzentrieren so viele Zeilen an Source zu schreiben wie es notwendig ist ein Problem auch deutlich und einfach verstehbar zu umschreiben. Deine Zielsetzung konzentiert sich auf ein Detail statt auf das gesammte Problem.
Zitat:
Zitat von
negaH:
5.) was nun ? IstPrim() oder IsPrime() ? aber nicht IsPrim() das ist denglish.
Wenn du genau hinschaust, wirst du feststellen, dass ich IstPrim geschrieben habe.
Hä, hast du das editiert ? Ich kann mich erinnern das dort noch IsPrim() stand. Falls nicht, sorry, ändert aber nichts an der Aussage ansich
Es bezieht sich ja nicht persönlich auf dich sondern gilt eher allgemein.
Zitat:
Zitat von
negaH:
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.
Ich bin Programmierer und kein Mathematiker.
Doch bist du, sind wir alle.
Die Hardware basiert auf der Boolschen Algebra, und in der Programmierung ist es immer von Vorteil auch ein bischen Mathematik zu beherrschen.
Davon abgesehen versucht, bei unserem speziellen Problem, ein Programmierer ein rein mathematisches Problem in eine Software umzusetzen. Es ist aber fatal eine Sichtweise an den Tag zu legen die im Grunde ignorant ist. Denn deine Aussage heist für mich persönlich das du eine mathemtische Aufgabe nicht deshalb mathematisch korrekt angehen möchtest weil du sagt "na und, ich bin Programmierer und kein Mathematiker". Das ist ignorant und meiner Meinung nach eben auch ein "schlechter Programmierstil". Programmierstil bedeutet nicht wie der Souce aussieht, nein das ist nur eine Wirkung der Ursache. Und die Ursache für einen guten Programmierstil ist die Frage WIE der Programmierer ein Problem lösst. Und handelt es sich um ein Problem der Mathematik dann sollte er es auch so angehen. An Hand des Sources kann man also durchaus erkennen ob ein Programmierer sachlich fundiert und sauber ein Problem angegangen ist. Ist dies der Fall dann ist der Source sauber formatiert, folgt einer Logik, ist nachvollziehbar und umschreibt das zu lösende Problem auch für Andere verständlich. Ein Source ist dann nicht nur ein Source sondern quasi ein Lehrbuch das mit eigener Sprache ein Problem erklärt.
Zitat:
Zitat von
negaH:
7.) Sonderfall 1 ist zu wenig und berücksicht eben nicht negative Zahlen
Hast du mir doch in 2.) schon gesagt?
Nicht nur. Ich meinte das man bei dieser schnellen "Eingangsüberprüfung" gleich nebenbei abprüfen kann
1.) ist Zahl ungerade ?
2.) ist Zahl größer 2 ?
Man schließt damit also implizit Zahlen aus die
1.) negativ sind
2.) gleich Null sind
3.) gleich Eins sind
4.) gleich dem Spezialfall der einzigsten gerade Primzahl 2 sind
5.) gerade Zahlen sind
Diese 5 Bedingungen werden mit
Result := Odd(N) and (N > 2);
abgefragt.
Zitat:
Zitat von
negaH:
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.
Ich programmiere Delphi, kein Pascal.
Und wieder eine Form der Ignoranz. (ich würde sogar sagen Trotzigkeit).
Es sollte im Bestreben jedes Programmieres sein nicht mit Scheuklappen rumzurennen, sondern auch andere Programmiersprachen und deren Konzepte zu erlernen und zu beherrschen.
Zitat:
Zitat von
negaH:
9.) wenn es geht sollte man immer auf unnötige Sprachkonstruke verzichten und statt dessen mit "mathematischen" Zuweisungen arbeiten.
Hast du dafür ein konkretes Beispiel?
Ja, das obige. Es enthält sogar 3 solcher Fälle:
Delphi-Quellcode:
Result := Odd(N) and (N > 2);
Result := N mod Candidate <> 0;
Result := N = 2;
statt
Delphi-Quellcode:
if Odd(N) then
if N > 2 then Result := True
else Result := False
else Result := False;
if N mod Candidate = 0 then
begin
Result := False;
Exit;
end;
Das eine ist eine mathematische Sichtweise, Denkweise als Formel. Das andere ist eine rein Algortihmische, ja fast schon Maschinen-denkweise.
Denn wie du siehst, benutzt man quasi eine mathematische Formel für die Umschreibung eines Sachverhaltes so ergibt sich auch automatisch der Fall das man eben nicht mit Exit; arbeiten muß, sondern stattdessen eine Result Variable zuweist und diese sauber als Bedingung in der while do Schleife als Abbruchbedingung abfragt.
Zitat:
Zitat von
negaH:
10.) wenn es geht exit/goto/continue vermeinden
Warum? Es ist doch die effizienteste Methode, hier aus der Schleife zu springen, oder sehe ich das falsch?
weil durch diese Anweisungen der aktuelle Programmblock irregulär verlassen oder weitergeführt wird.
Ein Exit zb. springt direkt aus dem aktuellen und hierarisch geschachtelten Programmblock und verlässt die komplette Funktion/Procedure. Exit zerstört also den grafisch hierarischen Source Aufbau, somit den Lesefluß eines anderen Programmieres und finally damit auch die Verständlichkeit.
Allerdings sehe ich diesen Punkt nicht allzu dramatisch, denn es gibt durchaus Fälle in denen ein goto/exit durchaus eine enorme Steigerung der Effizienz im erzeugten Code zur Folge hat.
Dies ist aber in unserem Beispiel eben nicht der Fall, ergo gibt es keine logische Begründung Exit noch zu verwenden.
Eines kann ich dir aber mit Sicherheit garantieren:
der Vorteil deines Exits ist so gering das es den Peformancevorteil meiner Funktion auf Grund der algorithmischen Verbesserungen unmeßbar gering ausfällt.
Zitat:
Zitat von
negaH:
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.
Hmm, da kann' ich so spontan nicht zustimmen. Was ist zum Beispiel mit 8? Die Wurzel von 8 ist 2, das dann nochmal geteilt durch 2 ist 1 und deine Schleife würde gar nicht ausgeführt!
Siehst du: ein guter Programmierstil fördert die Verständlichkeit beim Lesen durch Andere.
Anscheinend habe ich da aber vollständig versagt
sonst hättest du meine Source auch verstanden und erkannt das der Fall 8 = gerade Zahl garnicht, nein niemals garnicht never, in der while Schleife auftreten kann.
Wenn ich eine Funktion haben möchte die abfragt ob N eine Primzahl ist dann kann ich von vornherein mit Odd(N) 50% aller Zahlen sehr sehr effizient ausschließen, nämlich alle geraden Zahlen wie auch die 8.
Bei der eigentlichen Trialdivision werden also nur ungerade Zahlen überprüft. Auch da wiederum müssen wir nicht modulo jeder Zahl testen denn das minimal Set der Zahlen mit denen man Modulo testen muß sind alle Primzhalen bis Wurzel(N). Der Einfachheit halber nehmen wir alle ungeraden Zahlen, was 50% weniger ist als in deinem Falle, aber immer noch weit mehr als notwendig.
Gruß Hagen