Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi [Tutorial] Quadratische Gleichungen vollständig lösen (https://www.delphipraxis.net/137624-%5Btutorial%5D-quadratische-gleichungen-vollstaendig-loesen.html)

gammatester 28. Jan 2010 21:42

Re: Quadratische Gleichungen vollständig lösen
 
Erster Fehlerbericht: Bug zB für: a=1 b=0 c=1. Mit der beigepackten EEX: -> Meldung "p is a very small nummber" dann "ungültige Gleitkomma-Op", in der D6-IDE x1=NAN x2=NAN.

Die "kleines p"-Logik ist noch ziemlich daneben, denn nach Ausgabe "p is a very small nummber" wird sqrt(0-1) berechnet -> Crash. Erste Abhilfe für den Fall oben: Ersetze if (p>=0) and (p<sqrt(Math.MinDouble)) then durch if (p>0) and (p<sqrt(Math.MinDouble)) then

Ich sehe nicht, warum überhaupt soviel Aufhebes für "kleines p" gemacht wird. Kritisch sind hier eigentlich "nur" die Diskriminantenberechnung (und Overunder/flow). Ein Kriterium, wann die Diskriminante mit erhöhter Genauigkeit berechnet werden muß, findet man zB bei W.Kahan, On the Cost of Floating-Point Computation Without Extra-Precise Arithmetic http://www.eecs.berkeley.edu/~wkahan/Qdrtcs.pdf.

Gammatester

gammatester 29. Jan 2010 08:27

Re: Quadratische Gleichungen vollständig lösen
 
Ein weiterer Bug und zwei Vorschläge:

Bug:
a=1, b=1e140, c=1
ergibt
X1= -2,14326739881213E123
X2= -1E140
a wird zwar erst richtig mit Vieta berechnet, dann aber im else-Zweig von 'p<0' überschrieben.

Vorschlag 1:
Das Demo-Programm ist so geändert, das nur einmal die Gleichung gelöst wird, und nicht 6! (in Worten sechsmal) bei komplexen Lösungen.

Vorschlag 2:
Der "Small p"-Zweig wurde entfernt, wenn er beigehalten werden soll (wofür keine Notwendigkeit besteht, für kleine negative p wird er zB ja auch nicht benutzt!), muß eine Fallunterscheidung Diskriminante <0 und >=0 eingebaut werden.

Hier der vollständige Code.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Math, ComCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Edit4: TEdit;
    Edit5: TEdit;
    Button2: TButton;
    RichEdit1: TRichEdit;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  MySolution = Record
    a,b,d:double;
    c:integer;// 1: 2 real solution; 2: 1 real solution;
              // 3: 2 complex solutions
end;

//Wolfgang Mix - Delphi-PRAXiS
function SolveQuadraticEquation( a, b, c : Double ): MySolution;
var p, q , discriminant, discriminant2, re, im: Double;
begin
  //  ax² + bx + c = 0
  if (a = 0) then
  raise Exception.CreateFmt
     ('a should not be zero, no quadratic equation',[result.a]);
  p := b / a;
  q := c / a;

  //if p is a very big number - sqr(p/2) > MaxDouble
  if abs(p)>sqrt(Math.MaxDouble) then
  begin
    //code
    showmessage('p is a very big number');
    //showmessage(floattostr(Math.MaxDouble));
    result.a:=abs(p) + sqrt(0.25 - (q/p)/p);
    result.b:=abs(p) - sqrt(0.25 - (q/p)/p);
    result.c:=1;
    result.d:=0.25 - (q/p)/p;
    exit;
  end;

  //  calculate discriminant
  discriminant := sqr(p/2) - q;
  Result.d := discriminant;

  // calculate real value
  re:=-p/2;
  // calculate imaginary value
  im:=sqrt(abs(discriminant));
  //Form1.Edit7.Text:=FloatToStr(discriminant);

  if discriminant > 0 then
  begin // 2 solutions
    if p>=0 then
    begin
      Result.b := -p/2 - sqrt(discriminant);
      Result.a := q/Result.b;  //x1 mit Vieta
      Result.c := 1;
    end
    else begin
      Result.a := -p/2 + sqrt( discriminant);
      Result.b := q/Result.a;  //x2 mit Vieta
      Result.c := 1;
    end;
  end

  else

  if discriminant < 0 then
  begin // 2 complex solutions
     Result.a := re;
     Result.b := im;
     Result.c := 3;
  end
  else

  begin // 2 equal solutions
    Result.a := -p/2;
    Result.b := Result.a;
    Result.c := 2;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,discriminant: double;
    indicator:integer;
    qs: MySolution;

begin
   RichEdit1.Lines.Clear;
   a:=StrToFloat(Edit1.Text);
   b:=StrToFloat(Edit2.Text);
   c:=StrToFloat(Edit3.Text);
   if (a=0) then
   begin
     // Don't calculate
     showmessage ('a should not be zero, no quadratic equation');
     sleep(2000);
     exit;
   end
   else
   begin
     {WE: Gleichung nur einmal lösen und Ergebnisse anzeigen}
     qs := SolveQuadraticEquation(a,b,c);
     indicator := qs.c;
     case indicator of
       1: Begin
            Label1.Caption:='2 real solutions';
            RichEdit1.Lines.Add ('X1= ' + FloatToStr(qs.a));
            RichEdit1.Lines.Add ('X2= ' + FloatToStr(qs.b));
          End;
       2: Begin
            Label1.Caption:='1 real solution';
            RichEdit1.Lines.Add ('X= ' + FloatToStr(qs.a));
          end;
       3: Begin
            Label1.Caption:='2 complex solutions';
            RichEdit1.Lines.Add ('X1= ' + FloatToStr(qs.a)+
                                      ' + ' + FloatToStr(qs.b)+ ' i ');
            RichEdit1.Lines.Add ('X2= ' + FloatToStr(qs.a)+
                                      ' - ' + FloatToStr(qs.b )+ ' i ');
          End;
     end;
     discriminant:= qs.d;
     Edit4.Text:=FloatToStr(discriminant);
     Edit5.Text:=IntToStr(indicator);
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RichEdit1.Clear;
end;

end.

Wolfgang Mix 29. Jan 2010 08:56

Re: Quadratische Gleichungen vollständig lösen
 
@gammatester:

Vielen Dank, werde ich so übernehmen.

Liebe Grüße

Wolfgang

[edit]... und bug bei sehr großen Zahlen beseitigt [/Edit]

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Math, ComCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Button1: TButton;
    Label1: TLabel;
    Edit4: TEdit;
    Edit5: TEdit;
    Button2: TButton;
    RichEdit1: TRichEdit;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  MySolution = Record
    a,b,d:double;
    c:integer;// 1: 2 real solution; 2: 1 real solution;
              // 3: 2 complex solutions
end;

//Wolfgang Mix - Delphi-PRAXiS
function SolveQuadraticEquation( a, b, c : Double ): MySolution;
var p, q , discriminant, discriminant2, re, im: Double;
begin
  //  ax² + bx + c = 0
  if (a = 0) then
  raise Exception.CreateFmt
     ('a should not be zero, no quadratic equation',[result.a]);
  p := b / a;
  q := c / a;

//if p is a very big number - sqr(p/2) > MaxDouble
  if abs(p)>sqrt(Math.MaxDouble) then begin
    showmessage('p is a very big number');
    result.d := 0.25 - (q/p)/p;
    im := abs(p)*sqrt(abs(result.d));
    if result.d>0 then begin
      result.a := -p/2 - sign(p)*im;
      result.b := q/result.a;
      result.c := 1;
    end
    else if result.d<0 then begin
      Result.a := -p/2;
      Result.b := im;
      Result.c := 3;
    end
    else begin
      Result.a := -p/2;
      Result.b := Result.a;
      Result.c := 2;
    end;
    exit;
  end;

  //  calculate discriminant
  discriminant := sqr(p/2) - q;
  Result.d := discriminant;

  // calculate real value
  re:=-p/2;
  // calculate imaginary value
  im:=sqrt(abs(discriminant));
  //Form1.Edit7.Text:=FloatToStr(discriminant);

  if discriminant > 0 then
  begin // 2 solutions
    if p>=0 then
    begin
      Result.b := -p/2 - sqrt(discriminant);
      Result.a := q/Result.b;  //x1 mit Vieta
      Result.c := 1;
    end
    else begin
      Result.a := -p/2 + sqrt( discriminant);
      Result.b := q/Result.a;  //x2 mit Vieta
      Result.c := 1;
    end;
  end

  else

  if discriminant < 0 then
  begin // 2 complex solutions
     Result.a := re;
     Result.b := im;
     Result.c := 3;
  end
  else

  begin // 2 equal solutions
    Result.a := -p/2;
    Result.b := Result.a;
    Result.c := 2;
  end;

end;

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,discriminant: double;
    indicator:integer;
    qs: MySolution;

begin
   RichEdit1.Lines.Clear;
   a:=StrToFloat(Edit1.Text);
   b:=StrToFloat(Edit2.Text);
   c:=StrToFloat(Edit3.Text);
   if (a=0) then
   begin
     // Don't calculate
     showmessage ('a should not be zero, no quadratic equation');
     sleep(2000);
     exit;
   end
   else
   begin
     {WE: Gleichung nur einmal lösen und Ergebnisse anzeigen}
     qs := SolveQuadraticEquation(a,b,c);
     indicator := qs.c;
     case indicator of
       1: Begin
            Label1.Caption:='2 real solutions';
            RichEdit1.Lines.Add ('X1= ' + FloatToStr(qs.a));
            RichEdit1.Lines.Add ('X2= ' + FloatToStr(qs.b));
          End;
       2: Begin
            Label1.Caption:='1 real solution';
            RichEdit1.Lines.Add ('X= ' + FloatToStr(qs.a));
          end;
       3: Begin
            Label1.Caption:='2 complex solutions';
            RichEdit1.Lines.Add ('X1= ' + FloatToStr(qs.a)+
                                      ' + ' + FloatToStr(qs.b)+ ' i ');
            RichEdit1.Lines.Add ('X2= ' + FloatToStr(qs.a)+
                                      ' - ' + FloatToStr(qs.b )+ ' i ');
          End;
     end;
     discriminant:= qs.d;
     Edit4.Text:=FloatToStr(discriminant);
     Edit5.Text:=IntToStr(indicator);
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RichEdit1.Clear;
end;

end.

alzaimar 29. Jan 2010 12:37

Re: Quadratische Gleichungen vollständig lösen
 
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]

gammatester 29. Jan 2010 13:24

Re: Quadratische Gleichungen vollständig lösen
 
@alzaimar: Mit Deinem Vorschlag wären wir wieder am Asugangspunkt. Zwar verständlicher und hübscher, aber keinen Deut besser. Wenn nur die pq-Formel gut umgesetzt werden soll in mathematisch exakte Programmierung, trifft jfheins' Argument aus #19 wieder zu. Ich meine, daß ein Codelib-Beitrag doch mehr bringen sollte.

Dein Vorschlag ignoriert sämtliche angesprochen numerischen Probleme. Selbst der Hinweis auf extended zieht nicht, da die Diskriminante (nicht Determinante!) sqr(b) - 4*a*c eh schon extended gerechnet und dann in double gespeichert wird.

Auch tragen die von Dir gewählten Bezeichnungen Basis und Offset nicht zum Verständnis bei und sorgen eher für Verwirrung denn Klarheit.

Nix für ungut
Gammatester

jfheins 29. Jan 2010 15:38

Re: Quadratische Gleichungen vollständig lösen
 
Ich persönlich finde es übrigens eher unpraktisch, dass das Ergebnis "kodiert" ist (man muss also den Lösungstypen auswerten und eine case-Unterscheidung machen, um überhaupt etwas mit dem Ergebnis anfangen zu können ...)

Schöner wäre es, stattdessen 2 kurze Funktionen bereitzustellen: Zum Beispiel eine Funktion die immer 2 komplexwertige Nullstellen liefert und eine andere (für die, die keine komplexen Zahlen mögen/brauchen) die 2 double-Werte zurückliefert, von denen dann einer oder beide NaN sein können (falls es nur eine oder keine reelle Nullstelle gibt)

Wolfgang Mix 29. Jan 2010 16:03

Re: Quadratische Gleichungen vollständig lösen
 
@alzaimar
Zuerst einmal: Ich betrachte mich nicht als Profiinformatiker
sondern als vorangeschrittener Anfänger, zu mindestens in Delphi,
mit dem ich mich erst 1 Jahr versuche.
Die wissenschaftliche Weltsprache ist nun einmal Englisch.
Folgt man Deinem Vorschlag, sollte dann konsequenterweise
auch die gesamte Pascalsyntax eingedeutscht werden

Ich versuche, mich weitgehend an das Styleguide von Embarcadero
zu halten. Selbst das von Delhi-Treff nach deutsch übersetzte
Styleguide verwendet englische Kommentare und Bezeichner.
http://www.delphi-treff.de/delphi-styleguide/

Ein weiterer Grund für mich, diesen Stil beizubehalten ist,
daß hier nicht nur deutsches Publkum liest.

@gammatester

Danke für das hervorragende Scriptum von Prof. W. Kahan, das
ich mir nebenbei auch noch zu Gemüte führen werde. Leider habe
ich kein Mathlab, wäre deswegen aber dankbar für zu prüfende
Koeffitienten a,b und c mit demonstrativ ungenauen und genaueren
Ergebnissen.

@jfheins:

Im späteren Script werde ich schrittweise mit noch mehr Erklärungen
an diesen Brocken heranführen und Deinen Vorschlag mit übernehmen.

Ich merke langsam, das Tutorial wird zeitaufwendiger als ich
dachte, macht aber nix :)

gammatester 29. Jan 2010 19:10

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von Wolfgang Mix
...
Leider habe ich kein Mathlab, wäre deswegen aber dankbar für zu prüfende
Koeffitienten a,b und c mit demonstrativ ungenauen und genaueren
Ergebnissen.

Testfälle kann man einfach selbstbasteln. Hier ein kleines Beispiel:

Mit a=10^n, b=-2*10^n+2, c=10^n+2, also zB a=1000, b=-2002, c=1002. Mit den Deinen Bezeichnungen sind die Lösungen X1=1, X2=1+2/10^n und die Diskriminante D=1/10^(2n), und dies sind die Rechenergebnisse (erste Spalte ist n):

Code:
1  X1=1,2               X2=0,999999999999999    D=0,0100000000000002
2  X1=1,02              X2=1                    D=0,0001
3  X1=1,00199999999989  X2=1,00000000000011     D=9,99999999777763E-7
4  X1=1,0002            X2=1                    D=1,0000000000049E-8
5  X1=1,0000200000111   X2=0,999999999988896    D=1,00000222078706E-10
6  X1=1,00000199988897  X2=1,00000000011103     D=9,99777951399272E-13
7  X1=1,00000020110428  X2=0,999999998895723    D=1,02220749226278E-14

8  X1=1,00000001 + 1,10490345560989E-8 i
   X2=1,00000001 - 1,10490345560989E-8 i
    D=-1,22081164621868E-16
Sie zeigen auch schön, daß die Berechnung der Diskriminante der kritische Teil ist (mit der nicht gekürzten Formal ist sie immer b^2-4ac = 4!), und daß der Fehler in den Lösungen langsam nach "vorn kriecht" und ab n=8 reicht die genauigkeit nicht mehr aus.

Ich meine, daß im Rahmen der Delphi-Praxis und als Basis für ein Tutorial Deine jetzige Berechnungsroutine ausreicht. Wie schon von anderen gesagt, finde ich allerdings auch mM das Interface (also die Parameterübergabe) verbesserungswürdig.

In dem von Dir angehängten PDF wird zB vorgegeben:
Delphi-Quellcode:
procedure SolveQuadraticEquation(var Anzahl: integer; var IstKomplex: boolean; var x1,x2: double);
Ich verwende in meiner QuadSolv-Unit folgende Funktionen:

Delphi-Quellcode:
function squad(a,b,c: double; var x1,y1,x2,y2: double): integer;
  {-Solve the quadratic equation a*x^2 + b*x + c = 0. Result is the number}
  { of different solutions: 0 (if a=b=0), 1 (x1), or 2 (x1,x2). If the}
  { result is = -2, x1+i*y1 and x2+i*y2 are the two complex solutions.}
  { No precautions against over/underflow, NAN/INF coefficients return 0.}

function squadx(a,b,c: double; var x1,y1,x2,y2: double): integer;
  {-Solve the quadratic equation a*x^2 + b*x + c = 0. Result is the number}
  { of different solutions: 0 (if a=b=0 or INF/NAN), 1 (x1), or 2 (x1,x2).}
  { If the result is = -2, then x1 + i*y1 and x2 + i*y2 are the two complex}
  { solutions. Uses scaling by powers of two to minimize over/underflows.}

function squad_selftest: integer;
  {-Selftest for squad core routine, result=0 if OK, else number of the}
  { failing test case.}

Wolfgang Mix 30. Jan 2010 16:15

Re: Quadratische Gleichungen vollständig lösen
 
@gammatester:

Danke für die Test-Formel, die ist okay,
aber wie kommt man auf sowas :?:

Zitat:

Mit a=10^n, b=-2*10^n+2, c=10^n+2, also zB a=1000, b=-2002, c=1002. Mit den Deinen Bezeichnungen sind die Lösungen X1=1, X2=1+2/10^n und die Diskriminante D=1/10^(2n), und dies sind die Rechenergebnisse (erste Spalte ist n):

alzaimar 30. Jan 2010 17:10

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von Wolfgang Mix
@alzaimar: Zuerst einmal: Ich betrachte mich nicht als Profiinformatiker sondern als vorangeschrittener Anfänger, zu mindestens in Delphi,

Das behaupte ich auch nicht, sondern
Zitat:

Zitat von alzaimar
Ich würde mir wünschen, ...

Das sollten Ratschläge sein, die man beherzigen kann oder nicht. Da dich die paar Tipps nicht zu interessieren scheinen (nur 1-3), hege ich den Verdacht, das Dich verständlicher Code also nicht interessiert, und du als Anfänger nur eigene Fortschritte machen willst. Lehrer eben :mrgreen:

Zitat:

Zitat von Wolfgang Mix
Folgt man Deinem Vorschlag, sollte dann konsequenterweise auch die gesamte Pascalsyntax eingedeutscht werden

Das ist Blödsinn. Ich empfehle Dir das Buch 'Clean Code' von Robert C. Martin sowie die Diskussionen und Beiträge der Clean-Code-Developer Users Group als Grundlage für das Verfassen weiterer Statements auf diesem Gebiet.

Zitat:

Ein weiterer Grund für mich, diesen Stil beizubehalten ist, daß hier nicht nur deutsches Publkum liest.
Wieso schreibst DU dann auf deutsch? :stupid:
Ich dachte, es wird ein Tutorial und ein Tutorial würde in einer bestimmten Sprache geschrieben werden.
Ich dächte, das wäre dann Deutsch. Das Tutorial würde sich an eher Mathematikinteressierte richten, und weniger an Softwareentwickler.
Mir erscheint es nur konsequent, das deutsche Bezeichner und deutsche Kommentare in einem deutschen Tutorial für deutsche Mathematiker angebracht wären.

Anders herum machst Du deinem Namen alle Ehre, wenn du die Sprachen Mix't :zwinker:


Zitat:

Zitat von gammatester
@alzaimar: Zwar verständlicher und hübscher, aber keinen Deut besser.

Ach nee. Ich antworte mit Ausschnitten aus meinem Beitrag, vielleicht fällt der Groschen:
Zitat:

Weiterhin habe ich als Laie ... 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
Wie deutlich denn noch? :shock:

Ich schrieb also als 'Laie', der einen 'naiven Gegenvorschlag' macht, und weiß, das er damit 'sicherlich falsch' liegt. Klonk?

Man könnte meinen oder einen ähnlichen Code in das Tutoral einbringen, um anhand konkreter Beispiele zu zeigen, das die scheinbar triviale Lösung (von mir) ungenau ist. Mein Code sollte nur zeigen, das man es 'hübscher' hinbekommen kann.

Zitat:

Zitat von gammatester
Auch tragen die von Dir gewählten Bezeichnungen Basis und Offset nicht zum Verständnis bei und sorgen eher für Verwirrung denn Klarheit.

Na ja, ich glaube der Grad der Verwirrung ist beim bisherigen Code größer, aber grundsätzlich bin ich deiner Meinung, habe jedoch nur in der englischen Wiki entsprechende Nomenklaturen gefunden, die ich versucht habe, einzudeutschen. Aber besser als 're', 'im' und das völlige ignorieren des DRY-Prinzips sind sie allemal, oder bist du da anderer Meinung? Wenn ich dafür also z.B. 'w' und 'z' verwende, wäre die Verwirrung dann geringer? :zwinker:
Es gibt übrigens im Context der 'sauberen Programmierung' bei der Ausformulierung von Formeln auch das Bestreben, diese ohne Zwischenresultate zu kodieren (wenn es denn verständlich ist). Dies könnte hier durchaus geschehen.

Zitat:

Nix für ungut.. Gammatester
Och, da Du nicht richtig gelesen hast, ist das schon ok.

Wolfgang Mix 30. Jan 2010 18:05

Re: Quadratische Gleichungen vollständig lösen
 
@alzaimar:

Ich glaube, du hast meine Quelltexte nicht richtig gelesen.
Die Variablen Re, Im und indicator sind direkt kommentiert.
Für Kommentare und Bezeichner verwende ich die englische Sprache.
Den Grund dafür habe ich gennant.
Für mathematische Begriffe versuche ich, KORREKTE Bezeichner
zu haben, also z.B. disccriminant anstelle von "Determinante",
was etwas völlig anderes meint.
Im Übrigen waren wir hier bereits an einem Punkt angelangt,
Probleme von Auslöschung, Überlauf und Unterlauf zu erklären.
Dazu finde ich in "Deinem" Code nichts.

Was Lehrer betrifft würde ich mir wünschen, nur sachlich zu bleiben.
Was das Tut betrifft: Das wird selbstverständlich deutsch.


Gruß

Wolfgang

mkinzler 30. Jan 2010 18:25

Re: Quadratische Gleichungen vollständig lösen
 
Variabeln kann man schon in englisch verfassen, die Kommentierung würde ich aber in der Sprache der Zielgruppe erfassen ( in diesem Fall deutsch) oder in chinesich, so dass auch wirklich keiner mehr etwas davon hat. :stupid:

Wolfgang Mix 30. Jan 2010 18:34

Re: Quadratische Gleichungen vollständig lösen
 
ja gut, Ansichtssache, aber der Chinese und der Norweger hat mehr von englischer
Kommentierung. Dann muß Delphi-Treff sein verdeutschtes Styleguide
von Embarcadero ändern.
Aber egal, im TUT wirds sowieso komplett deutsch, und wenn gewünscht wird,
die Kommentare zu verdeutschen, mache ich das. Ich würde jetzt aber lieber
beim eigentlichen Thema bleiben oder abschließen.

alzaimar 30. Jan 2010 19:48

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von Wolfgang Mix
@alzaimar: Ich glaube, du hast meine Quelltexte nicht richtig gelesen.

Wie käme ich dann dazu, Verbesserungsvorschläge zu machen?
Zitat:

Zitat von Wolfgang Mix
Die Variablen Re, Im und indicator sind direkt kommentiert.

Kommentare sind in sauberem Code überflüssig, im Gegenteil: Sie sind zu vermeiden, denn der Code sollte selbsterklärend sein. Nur komplexe mathematische Formeln bilden hiervon eine Ausnahme.

Zitat:

Für mathematische Begriffe versuche ich, KORREKTE Bezeichner zu haben, also z.B. disccriminant anstelle von "Determinante", was etwas völlig anderes meint.
Stimmt. Ich habe meinen Code entsprechend geändert.
Schauen wir uns also deinen Code an:
Wozu steht in deinem Code die 'Discriminant2'? Was meinst du damit?
Was ist ein 'Re'? Webster sagt dazu "a rare heavy polyvalent metallic element", "an ancient hawk-headed Egyptian sun" oder gar "the syllable naming the second (supertonic) note of any major scale in solmization".
Das "Im" ist gar nicht bekannt.

Bitte definiere dein Verständnis von "KORREKTE Bezeichner".

Zitat:

Im Übrigen waren wir hier bereits an einem Punkt angelangt...Probleme von Auslöschung, Überlauf und Unterlauf zu erklären...Dazu finde ich in "Deinem" Code nichts.
:wall: Hast Du meine Beiträge überhaupt gelesen? Soll ich nochmal wiederholen, was ich geschrieben habe?
Erstmal ein Zitat aus meinem Beitrag:
Zitat:

Zitat von alzaimar
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

Was halte ich also von meinem Code? Was halte ich von Deinem Code (du bist doch Wolfgang)? Was wollte ich verdeutlichen? Junge Junge...

But as you prefer english, as english is a widely understood language and obviously the standard language of mathematicans, read this: I supplied a naive alternative (german: "naiven Gegenvorschlag") sample code to show how a clean code could be written. I also mentioned that the code would most likely fail (german: "sicherlich falsch"), as it was written by an amateur (german: 'Laie') and pointed out that the original code by Wolfgang is predominant.
Verstehst Du das?

Zitat:

Was das Tut betrifft: Das wird selbstverständlich deutsch.
Aber ich denke, du gehst davon aus, das auch
Zitat:

Zitat von Wolfgang Mix
... der Chinese und der Norweger ...

das Tutorial lesen wird?

Ich verstehe deine Borniertheit ehrlich gesagt nicht. Du bist ein sehr kompetenter Mathematiker, deine Ausführungen zu den quadratischen Gleichungen und die Erklärungen zu den Fallstricken finde ich sehr interessant, Du bereitest das Thema sehr gut auf. Top!

Im Kodieren bist Du nicht so gut. Musst Du auch nicht. Dazu gibt es andere, die im Gegenzug mathematische Dorfdeppen sind, dafür aber wissen, wie man sauberen Code schreibt.

Beides zusammen ergäbe ein wirklich brauchbares Tutorial. 60% bringen nichts. Weder dein Teil, weder die Beispiele und Anregungen vom gammatester, noch meine Anregung.
Allerdings wäre ich (u.v.a.) in der Lage, mit deinen Ausführungen und den Beispielen vom gammatester sowohl eine saubere Implementierung hinzulegen, als auch eine Begründung zu verfassen, die inhaltlich korrekt wäre, indem ich mich von euch beiden belehren ließe.

Du hingegen nicht.

Das unterscheidet uns wohl.

gammatester 30. Jan 2010 20:30

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von alzaimar
Aber besser als 're', 'im' und das völlige ignorieren des DRY-Prinzips sind sie allemal, oder bist du da anderer Meinung? Wenn ich dafür also z.B. 'w' und 'z' verwende, wäre die Verwirrung dann geringer?

Ja in der Tat. 're' und 'im' sind eingeführte mathematische Begriffe, 'offset' und 'basis' sind auch Standardbegriffe, die aber auch absolut gar nichts mit 're' und 'im' zu tun haben und hier völlig Fehl am Platz sind. Und 'w' und 'z' wären hier allemal besser als 'basis' bzw. 'offset', weil damit ziemlich offensichtlich wird, daß sie nur als temporäre Variable verwendet werden sollen.

Hier geht es um Probleme, eine mathematisch relativ einfache Formel so zu implementieren, daß ohne Riesenaufwand für viele Fälle brauchbare Ergebnisse erzielt werden. Das war auch erreicht, bevor Du mit Deinem, wie Du selbst sagt, laienhaft und naiven Codevorschlag fast alles über Bord geworfen hast. Über Codierstil etc, Verwendung gemeinsamer Ausdrücke etc. kann man diskutieren. Ich habe minimal-invasive Vorschläge gemacht, und wenn Du den mathematisch-numerischen Teil im Kern gelassen und verbessert hättest, wäre es OK gewesen; ich denke, daß auch Wolfgang nichts dagegen hätte.

Kommentare zu den anderen Polemiken, verkneife ich mir, da sie die Sache nicht voranbringen.

gammatester 30. Jan 2010 20:40

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von alzaimar
Was ist ein 'Re'? Webster sagt dazu "a rare heavy polyvalent metallic element", "an ancient hawk-headed Egyptian sun" oder gar "the syllable naming the second (supertonic) note of any major scale in solmization".
Das "Im" ist gar nicht bekannt.
..
Ich verstehe deine Borniertheit ehrlich gesagt nicht.

Und ich verstehe Deine Ignoranz nicht: Statt zu fragen, was 'Re' und 'Im' bedeutet, machst Du ein großes Theater. Das sind mathematische Bezeichnungen, die eigentlich schon auf dem Gymnasium bekannt sein sollten, spätestes im Studium, das auch nur ein wenig mit Mathe zu tun hat. Re = Realteil, Im = Imaginärteil.


Auch hier verkneife ich mir weitere Kommentare.

mkinzler 30. Jan 2010 20:49

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
@gammatester: Nicht jeder hat Mathematik studiert. Und wer es hat, benötigt höchstwahrscheinlich dieses Tutorial nicht!

gammatester 30. Jan 2010 21:11

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von Wolfgang Mix
@gammatester:

Danke für die Test-Formel, die ist okay,
aber wie kommt man auf sowas :?:

Zitat:

Mit a=10^n, b=-2*10^n+2, c=10^n+2, also zB a=1000, b=-2002, c=1002. Mit den Deinen Bezeichnungen sind die Lösungen X1=1, X2=1+2/10^n und die Diskriminante D=1/10^(2n), und dies sind die Rechenergebnisse (erste Spalte ist n):

Ist relativ schnell erklärt:

Man nehme die Doppelwurzel x1=x2=1, das gibt die quadratische Gleichung x^2 - 2x + 1 = 0, also a=1, b=-2, c=1. Jetzt wird x2 ein wenig gestört, also zB x2=1+e (e wie Epsilon). Das ergibt gibt dann a=1, b=-(2+e), c=1+e. Man kann für e jeden Wert einsetzen. Einen leicht sichtbare Effekt erhält man, wenn e = 1/10^n ist, oder was ich genommen habe e=2/10^n. Um schon Fehler in den Koeffizienten zu vermeiden, multipliziere
man noch mit 10^n.

Wolfgang Mix 30. Jan 2010 21:14

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Kommt Ihr bitte zum Thema zurück, oder ich werde versuchen,
mir gammatesater das Thema abzuschließen, wenn er dazu bereit ist

gammatester 30. Jan 2010 21:17

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von mkinzler
@gammatester: Nicht jeder hat Mathematik studiert. Und wer es hat, benötigt höchstwahrscheinlich dieses Tutorial nicht!

Richtig, nicht jeder hat Mathe studiert. Aber dann sollte man sich vielleicht auch nicht so aus dem Fenster lehnen mit mathematisch bzw. numerisch unqualifizierten Vorschlägen. Im überigen bedeutet Mathestudium nicht unbedingt, daß man das numerische Problem lösen kann. Mathematisch ist eine quadratische Gleichung (fast) trivial.

mkinzler 30. Jan 2010 21:18

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
@Wolfgang: Daniel, hat uns nicht darüber informiert, dass du zum Supermoderator ernannt wurdest.

Ja ich glaube du solltest das mit gammatester zusammen abchliessen, da du/ihr sowieso an keinen Anregungen anderen interessiert seid bzw. diese nicht euer Wissensniveau teilen.

Wolfgang Mix 30. Jan 2010 21:23

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
:) Man müßte schon Grundlagen in Mathematik und Englisch beherrschen

alzaimar 30. Jan 2010 21:26

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von gammatester
Und ich verstehe Deine Ignoranz nicht: Statt zu fragen, was 'Re' und 'Im' bedeutet,

Wieso soll ich fragen, der Code soll es mir beantworten. Ich weiss ja nicht, für wen du so Code schreibst, aber ich steh doch nicht auf und lauf in der Abteilung herum, um den Knilch zu finden, der seine Variablen 're' und 'im' oder 'frzl' und 'mpft' nennnt? Gut, hier mag das noch aus dem Kontext hervorgehen, aber für ein T-u-t-o-r-i-a-l ist das etwas kryptisch, findest du nicht?

Zitat:

Das sind mathematische Bezeichnungen, die eigentlich schon auf dem Gymnasium bekannt sein sollten, spätestes im Studium, das auch nur ein wenig mit Mathe zu tun hat.
Hoho gammatester, halt mal die Luft an, ich zieh auch nicht über deine Herkunft oder deinen Codestil her.
Zitat:

Zitat von gammatester
Re = Realteil, Im = Imaginärteil.

Und wieso *heißen* die Variablen dann nicht so?

Wenn das die deutschen Abkürzungen sind, was hat das dann in einem Code zu suchen, der vorgibt, englische Bezeichner zu verwenden?

Übrigens gammatester,
Zitat:

Und ich verstehe Deine Ignoranz nicht: ...
Hatten wir uns einander so vorgestellt?

Als Friedensangebot ein Vorschlag, der hoffentlich alle Kritikpunkte eliminiert, und die Erfahrungen in einen lesbaren und kommentarlosen Code zu gießt, der englische Bezeichner verwendet. Ich find sie auch schöner, ich gebs ja zu.

Über zu kurze, zu lange und korrekte Bezeichner lässt sich -wie immer- streiten. So weiss ich z.B. nicht, ob die Teilösung wirklich von Vieta ist (stand teilweise so im W.Mix-Code) und ob das mit den Diskriminanten immer stimmt.

Delphi-Quellcode:
unit QuadraticEquationSolver;

interface
uses
  SysUtils;

type
  EInvalidAccessException = class(Exception);
  TQuadraticEquationSolutionType = (stUndefined, stReal, stSingle, stComplex);
  TQuadraticEquationSolver = class
  private
    FSolutionType: TQuadraticEquationSolutionType;
    FSolution2: Double;
    FDiscriminant: Double;
    FSolution1: Double;
    FRealPart: Double;
    FComplexPart: Double;
    procedure SetSingleSolution(solution: Double);
    procedure SetRealSolutions(solution1, solution2: Double);
    procedure SetComplexSolution(realPart, complexPart: Double);
    procedure SolveUsingVietaFormula(p, q: Double);
    procedure SolveUsingTransformedFormula(p, q: Double);
    function IsAPositiveAndVeryLargeNumber(n: Double): Boolean;

    function GetSolution1: Double;
    function GetSolution2: Double;
    function GetRealPartOfSolution: Double;
    function GetComplexPartOfSolution: Double;
  public
    constructor Create;
    procedure Solve(a, b, c: Double);
    property SolutionType: TQuadraticEquationSolutionType read FSolutionType;
    property Solution1: Double read GetSolution1;
    property Solution2: Double read GetSolution2;
    property RealPartOfComplexSolition: Double read GetRealPartOfSolution;
    property ComplexPartOfComplexsolution: Double read GetComplexPartOfSolution;
  end;

implementation
uses Math;
{ TQuadraticEquationSolver }

{$Region 'Solving and Mathematics'}
procedure TQuadraticEquationSolver.Solve(a, b, c: Double);
var
  p,q : Double;

begin
  Assert (Not IsZero(a), 'a must be nonzero');
  p := b / a;
  q := c / a;
  if IsAPositiveAndVeryLargeNumber(p) then
    SolveUsingTransformedFormula(p, q)
  else begin
    FDiscriminant := sqr(p / 2) - q;
    case Sign(FDiscriminant) of
      +1: SolveUsingVietaFormula(p, q);
      0 : SetSingleSolution(-p / 2);
      -1: SetComplexSolution(-p / 2, Sqrt(abs(FDiscriminant)));
    end;
  end
end;

procedure TQuadraticEquationSolver.SolveUsingVietaFormula(p, q: Double);
var
  solution: Double;

begin
  solution := -p / 2 - sign(p) * sqrt(FDiscriminant);
  SetRealSolutions(solution, q / solution);
end;

procedure TQuadraticEquationSolver.SolveUsingTransformedFormula(p, q: Double);
var
  root: Double;

begin
  FDiscriminant := (1 / 4 - (q / p) / p);
  root := sqrt(FDiscriminant);
  SetRealSolutions(abs(p) - root, Abs(p) + root);
end;

function TQuadraticEquationSolver.IsAPositiveAndVeryLargeNumber(n: Double): Boolean;
begin
  Result := (abs(n) > sqrt(Math.MaxDouble));
end;

{$EndRegion}

{$Region 'Routines for setting the individual solutions'}
procedure TQuadraticEquationSolver.SetComplexSolution(realPart, complexPart: Double);
begin
  FSolutionType := stComplex;
  FRealPart := realPart;
  FComplexPart := complexPart;
end;

procedure TQuadraticEquationSolver.SetRealSolutions(solution1, solution2: Double);
begin
  FSolutionType := stReal;
  FSolution1 := solution1;
  FSolution2 := solution2;
end;

procedure TQuadraticEquationSolver.SetSingleSolution(solution: Double);
begin
  FSolutionType := stSingle;
  FSolution1 := solution;
  FSolution2 := solution;
end;
{$EndRegion}

{$Region 'Property access'}
function TQuadraticEquationSolver.GetSolution1: Double;
begin
  if SolutionType = stComplex then
    raise EInvalidAccessException.Create('Access only if solution is not complex');
  Result := FSolution1;
end;

function TQuadraticEquationSolver.GetSolution2: Double;
begin
  if SolutionType = stComplex then
    raise EInvalidAccessException.Create('Access only if solution is not complex');
  Result := FSolution2;
end;

function TQuadraticEquationSolver.GetRealPartOfSolution: Double;
begin
  if SolutionType <> stComplex then
    raise EInvalidAccessException.Create('Access only if solution is complex');
  Result := FRealPart;
end;

constructor TQuadraticEquationSolver.Create;
begin
  FSolutionType := stUndefined;
end;

function TQuadraticEquationSolver.GetComplexPartOfSolution: Double;
begin
  result := FComplexPart;
end;
{$EndRegion}
end.
Die Essenz ist die 'Solve'-Methode, die -denke ich- die Lösungsansätze von W.Mix und GT dokumentiert. Der Rest ist Mumpfe.
Das Dilemma, das Lösung sowohl reale als auch komplexe Lösungen liefert, habe ich habe ich durch unterschiedliche Properties versucht, zu lösen.

Reelle Lösungen (eine oder zwei) stehen in den Eigenschaften 'Solution1' und 'Solution2', die komplexen in 'RealPartOfComplexSolution' und 'ComplexPartOfComplexsolution'. Etwas lang, finde ich.

Aber so fragt keiner nach. :zwinker: Bei 'Solution1' und 'Solution2' vielleicht schon... :gruebel:

[edit]Seit wann werden Rechtschreibfehler vom DCC nicht erkannt? [/edit]
[edit]Fehler beim Refaktorisieren dank gammatester beseitigt. [/edit]

gammatester 30. Jan 2010 22:37

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Code:
[Error] QuadraticEquationSolver.pas(43): Invalid compiler directive: 'Region'
[Error] QuadraticEquationSolver.pas(89): Invalid compiler directive: 'EndRegion'
[Error] QuadraticEquationSolver.pas(91): Invalid compiler directive: 'Region'
[Error] QuadraticEquationSolver.pas(112): Invalid compiler directive: 'EndRegion'
[Error] QuadraticEquationSolver.pas(114): Invalid compiler directive: 'Region'
[Error] QuadraticEquationSolver.pas(145): Invalid compiler directive: 'EndRegion'
[Fatal Error] Unit1.pas(23): Could not compile used unit 'QuadraticEquationSolver.pas'
Wenn man das beseitigt hat, gibt's das nächste Problem. Wieviele Beispiele hast Du mit Deinem Code getestet? Mit a=1, b=-3, c=2. Gibt's erstmal 'nen Crash "a must be non-zero"! Da der Code ja selbst erklärend ist, fragt sich der geneigte User wieso ist a=1 zero?

gammatester 30. Jan 2010 22:52

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Ein hoch auf "lesbaren und kommentarlosen Code"! Wenn man den schlimmen Bug aus #64 beseitigt hat, kommt der "lesbaren und kommentarlosen Code" doch tatsächlich zu dem Ergebnis, das x^2 - 3x + 2 = 0 die Lösungen hat x1=3, x2=0.666666666666667!

Na denn gute Nacht!

Gammatester

Hinweis: die Lösungen sind x1=1 und x2=2.

stoxx 30. Jan 2010 23:15

Re: Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von Wolfgang Mix
Leider habe ich kein Mathlab


dafür nehme man qtoctave


http://qtoctave.wordpress.com/download/


für kleine Aufgaben im Prinzip genau dasselbe wie matlab

alzaimar 31. Jan 2010 03:59

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
gammatester, nu beruhig dich doch mal. Ich habe dich doch mit keiner Silbe angegriffen oder beleidigt oder sonstwas. Mir sind halt zwei blöde Fehler unterlaufen, die ich inzwischen im Code behoben habe. Danke übrigens für deine Hinweise. Über die Art und Weise kann man zwar geteilter Meinung sein, aber jeder hat eben sein eigenes Niveau.

Chemiker 31. Jan 2010 08:35

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Hallo,

erst mal finde ich nicht schlecht wie ihr das Problem aufbereitet.

Nur in einem Punkt muss ich alzaimar recht geben, wenn man für einem deutschen Forum ein Tut. schreibt sollten auch die Kommentare und Bezeichner deutsch sein, oder man schreibt alles auf Englisch. Der Norweger oder Chinese wird sich schon zu helfen wissen, wenn er in einem deutschen Forum unterwegs ist.

Bis bald Chemiker

Daniel 31. Jan 2010 08:52

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
:roll:

Leute ... einige von Euch mögen brillante Mathematiker sein, andere brillante Codierer. Hier wird gekeilt um Begriffe und nun sogar um Compiler-Direktiven wie $REGION, die für das eigentliche Problem völlig irrelevant sind.

Es wäre schön, wenn Ihr die Verhältnismäßigkeiten wiederherstellen könntet und so die Inhalte, die in diesem Thema bereits versammelt sind, zu einer ganzheitlichen Lösung zusammenführen könntet. Denn von allen beteiligten Fachrichtungen ist das Problem ja nun schon gelöst.

Wolfgang Mix 31. Jan 2010 10:07

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Ich bin weder ein brillianter Mathematiker noch ein perfekter Codierer,
habe halt nur Spaß auf Algorithmen. Wenn man sich draußen ein bißchen
abgekühlt hat und einen warmen Tee genießt, kommt man vielleicht zu
folgender Erkenntnis:
Das Problem dieses Themas ist, daß wir, in welcher Programmiersprache
auch immer, nur einen kleinen begrenzten Zahlenbereich aus der Menge
der reellen Zahlen haben, selbst beim Typ Extended und bei Berechnungen
Rundungsfehler entstehen, der begrenzte Zahlenbereich unter/überschritten
werden kann und Fehler durch Auslöschung entstehen können.
Die Ausgangsformeln sind perfekt und welweit 1000-fach bewiesen.
Ob man nun die eine oder andere Formel benutzt, ist völlig egal.
Es gibt aber einige Mögtlichkeiten Fehler zu vermeiden, wenn man
mit den wenigen Maschinenzahlen rechnet. Nicht mehr und nicht weniger
soll mein Beitrag zeigen. Wenn man sich ein wenig bei den Unis
umschaut, wird man auch nicht viel mehr dazu finden.
Ich denke, vom Material her gesehen, haben wir jetzt genug, um alles
nüchtern zusammen zu fassen.

Gruß an alle

Wolfgang

gammatester 31. Jan 2010 11:49

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Zum alzaimar-Code - ein Vorschlag und drei Bugs:

V: Wenn man schon für die einmalige Abfrage (abs(n) > sqrt(Math.MaxDouble)) eine eigene Funktion spendiert: IsAPositiveAndVeryLargeNumber sollte dann doch besser IsAVeryLargeNumber heißen, da ja abs(n) getestet wird. (Wieso eigentlich 'n'?)

B1: Außerdem ist die sqrt(MaxDouble)-Logik noch nicht richtig implementiert. Mit s=sqrt(MaxDouble) hat x^2 +s + s^2 = 0, d.h. a=1, b=s, c=s^2, angeblich 2 relle Lösungen, leider allerdings beide =NAN in der IDE, Exception außerhalb. Tatsächlich gibt es, wie man leicht nachrechnet, zwei konjugiert komplexe Lösungen x1,x2 = 0.5*(1 +/- sqrt(3)*i)*s.

B2: Weiter hat x^2 - 1e160*x + 0 = 0 angeblich die Lösungen x1=x2=1e160, richtig ist x=1e160, x2=0.

B3: Und wiedermal das unsägliche iszero-Problem, das wir eigentlich schon ad acta gelegt hatten: Der Code weigert sich die Lösungen x1=1, x2=2 von (rx)^2 - 3r(r*x) + 2r^2 = 0 zu berechnen für abs(r) <= 1e-6.

Noch eine Bemerkung zu Daniels "Compiler-Direktiven wie $REGION, die für das eigentliche Problem völlig irrelevant sind." In dem Codelib-Beitrag bitte bitte entfernen, da sie ja offensichtlich irrelevant sind, aber zumindest bis Delphi 10 das Kompilieren verhindern.

Gruß Gammatester

Der.Kaktus 31. Jan 2010 11:54

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
[OT]
Herzlichen Glückwunsch dem "Threaderöffner" zum "runden" Geburtstag..alles Gute usw... geballt mit der Summe an Beiträgen (dato "777")..wenn das nichts ist !?
:cheer:
[/OT]

Wolfgang Mix 31. Jan 2010 12:08

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
@Der.Kaktus:

[OT] Danke für die Glückwünsche [/OT] :)

Wolfgang Mix 19. Feb 2010 20:41

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Liebe DPler,

die Diskussion im thread fand ich richtig gut und danke allen
noch einmal für die rege Beteiligung. Inzwischen habe ich mir
gedacht, das Tut auf das Wesentliche zu beschränken, nämlich
auf die wesentlichen Probleme der Numerik, ohne Codebeispiele
zu bevorzugen. Im thread gab es ja genügend gute Beispiele.
Das nun gekürzte Tut habe ich Frederic am 02.02. zukommen
lassen, damit er mit seinen Comoderatoren entscheiden kann,
wo es untergebracht werden kann oder was man noch ändern
sollte. Lassen wir Ihnen Zeit!
Euch "normalen" Usern will ich den Entwurf aber nicht vorenthalten
und hänge ihn an Post #1 an.

Liebe Grüße

Wolfgang

SirThornberry 20. Feb 2010 09:10

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Was hat dieses Tutorial eigentlich mit Delphi zu tun? Ich hab darin rein gar nichts entdeckt was mit Delphi zu tun hat und somit in die Codelib sollte (nach meiner persönlichen Meinung) :gruebel:
Anders ausgedrückt: Gehört so etwas nicht in eine Mathematikforum? Und dort wäre es vermutlich zu simpel um das sich jemand der Sache annimmt.
Ich dachte immer in die Codelib sollen wichtige Dinge die ein Jeder gebrauchen kann und nicht gaaaanz viele gaaaanz spezielle Dinge die nur ein einziger in 20 Jahren einmal benötigt :?

Dies ist meine ganz persönliche Meinung und ist somit nicht automatisch die Meinung des gesamten Teams

fkerber 20. Feb 2010 15:18

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Hi!

Es soll ja gar nicht mehr in die Codelib ;)
Es ist als Tutorial gedacht (also auch dann später in die Sparte) und behandelt ein Problem, dass afair nur bei Computer-Berechnung auftritt und somit in einem Mathematik-Forum eher nicht passt, aber bei allen Programmiersprachen quasi auftritt.
Insofern ist es doch ein Tutorial für allgemeines Programmieren, oder?


Grüße, Frederic

P.S.
Auch nur persönliche Meinung ;)

Wolfgang Mix 20. Feb 2010 15:25

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Ich denke, es paßt in beide Sparten, wenn man den Thread bestehen läßt,
meine Meinung. Im Tut gibt es ja einen Link auf diesen Thread.

mkinzler 20. Feb 2010 18:25

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Zitat:

Dies ist meine ganz persönliche Meinung und ist somit nicht automatisch die Meinung des gesamten Teams
was aber auch nicht heisst, dass das Team hier anders denkt, sondern er nicht für alle spricht

Wolfgang Mix 20. Feb 2010 19:10

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Ich lasse einfach das Team entscheiden, und gut ist es.
Die Mods können ja dann die persönlichen Dinge und Polemiken
aus dem Thread herausnehmen.

Gruß

Wolfgang

alzaimar 20. Feb 2010 19:40

Re: [Tutorial] Quadratische Gleichungen vollständig lösen
 
Zitat:

Zitat von Wolfgang Mix
Die Mods können ja dann die persönlichen Dinge und Polemiken aus dem Thread herausnehmen.

Eine Zensur findet in diesem Forum nicht statt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:27 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz