Einzelnen Beitrag anzeigen

alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#44

Re: Quadratische Gleichungen vollständig lösen

  Alt 29. Jan 2010, 13:37
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]
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat