Ich würde mir wünschen, wen der Code einige Grundregeln sauberer Programmierung umsetzen würde:
1. Bezeichner sind nicht selbsterklärend. ('Im', 'Re', Feldbezeichner '.indicator', '.a'). Die Parameter a,b,c sind ok, denn das ist einschlägig bekannt.
2. Code-Styleguides werden ignoriert (Typen fangen z.B. in Delphi mit 'T' an)
3. Magic Numbers (case indicator of)
4. DRY-Prinzip ignoriert (mehrfache Verwendung fast identischer Faktoren/Formeln).
5. Verwendung englischer Bezeichner in einem deutschne Beispielcode.
5. Verwendung englischer Kommentare in einem deutschen Beispielcode.
Weiterhin habe ich als Laie nicht begriffen, wo die Vorteile dieser sehr komplexen Lösung sind. Ich hätte gern ein paar numerische Beispiele, um die Vorteile zu erkennen. Ich kann mir das PDF ja durchlesen, aber einige Beispielrechnungen, anhand derer man die Klimmzüge nachvollziehen kann, wären für ein Tutorial und das Verständnis sehr hilfreich.
Als Laie kann ich mir nämlich vorstellen, das das Problem der ziemlich großen Zahlen durch verwendung eines Extended-Zwischenresultats vermieden werden könnte (ich liege das sicherlich falsch, aber bis zur Behauptung des Gegenteils...).
Hier der naive Vorschlag mit dem Versuch 1-5 zu vermeiden. Der Code sollte selbsterklärend sein (ist aber ungetestet):
Delphi-Quellcode:
Type
TQuadratischeGleichungLoesungstyp = (qlEineLoesung, qlZweiLoesungen, qlKomplexeLoesungen);
TLoesungEinerQuadratischenGleichung = Record
LoesungsTyp : TQuadratischeGleichungLoesungstyp;
Loesung1,
Loesung2 : Double;
end;
Function LoeseQuadratischeGleichung (a,b,c : Double) : TLoesungEinerQuadratischenGleichung;
Var
basis,
diskriminante,
offset : Extended;
begin
If IsZero(a) Then
Raise EDivByZero.Create('Es wurde ein ungültiger Parameter angegeben (a darf nicht null sein)');
basis := -b / (2*a);
diskriminante := sqr(b) - 4*a*c;
offset := sqrt(abs(diskriminante)) / (2*a);
if diskriminante<0 then begin
result.LoesungsTyp := qlKomplexeLoesungen;
result.Loesung1 := basis;
result.Loesung2 := offset;
end
else if diskriminante>0 then begin
result.LoesungsTyp := qlZweiLoesungen;
result.Loesung1 := basis - offset;
result.Loesung2 := basis + offset;
end
else begin
result.LoesungsTyp := qlEineLoesung;
result.Loesung1 := basis;
result.Loesung2 := result.Loesung1;
end;
end;
Wenn man den numerisch sicherlich stabileren Code von Wolfgang hinsichtlich der Nomenklatur anpasst, könnte man beide Verfahren nehmen, um anhand von Beispielen die Überlegenheit des hier vorgestellten Codes zu verdeutlichen.
Das wäre dann ein Paradebeispiel für mathematisch exakte Programmierung, und das sie nicht trivial ist.
[edit]'determinante' durch 'diskriminante' ersetzt, dank W.Mix[/edit]