Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Taschenrechner->Graphen zeichenen (https://www.delphipraxis.net/142236-taschenrechner-graphen-zeichenen.html)

Delphi-Narr 24. Okt 2009 09:54


Taschenrechner->Graphen zeichenen
 
Hallo,

ich hab ja jetzt einen Taschenrechner mit Punkt vor Strich (s. Taschenrechner Term in FLießkommazahl)

Dieses Prinzip möchte ich verwenden, um auch eine Variable einzubauen, die vom Programm immer verändert wird.
So soll ein Graph zu einer Funktion entstehen.

Hier mein Ansatz:
Delphi-Quellcode:

Function TForm1.ParseAndCalc(Const X:Real;Const S: String): String; //X hat jetzt den Beispielwert 1 (s.u)
  Var SL: TStringList;
    i:   Integer;

  Begin
    SL := TStringList.Create;
    Try
      Try
        SL.Add('');
        For i := 1 to Length(S) do
          Case S[i] of
            '0'..'9', ',','.': Begin
              SL[SL.Count - 1] := SL[SL.Count - 1] + S[i];
            End;
            '*', '/', '+', '-','X': Begin //X wird hier in eine eigene Zeile geschrieben, damit nicht so etwas wie 3X entsteht
              If SL[SL.Count - 1] = '' Then Begin
              SL.Delete(SL.Count - 1);
              End;
              SL.Add(S[i]);
              SL.Add('');
              SL.SaveToFile('Dateipfad\SL.txt');//Nur zum Test, wie die SL erstellt wird:
               {Hier ist das Problem: Eingabe von X+1 wird nur gespeichert:
               X
               +
               
               Die 1 fehlt. 1+X ist kein Problem...??? Also ist wahrscheinlich hier der Fehler.
               Wenn ich jetzt auf den Button klicke kommt die Meldung, X sei kein gültiger Gleitkommawert...}
            End;
            ' ': ; // ignoriere Leerzeichen
            Else Raise Exception.CreateFmt('Ungültiges Zeichen "%s" gefunden.', [S[i]]);
          End;
          begin
               begin
               i:=0;
               while i < SL.Count do
                  begin
                      if SL[i]='*' then
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])*StrToFloat(SL[i+1])));
                               {Zahl vor und nach dem * werden multipliziert und in die Zeile der ersten Zahl geschrieben???} 
                               SL.Delete(i);
                               {Jetzt soll die Zeile des Operators gelöscht werden} 
                               SL.Delete(i);{und die der zweiten Zahl} 
                               {etwas wurde gefunden - fange von vorn an} 
                               i := i-1;
                         end
                      else
                      if SL[i]='/' then
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])/StrToFloat(SL[i+1])));
                               SL.Delete(i);
                               SL.Delete(i);
                               i := i-1;
                         end
                      else
                         i := i + 1;
                  end;
               i:=0;
               while i < SL.Count do
                  begin
                      if SL[i]='+' then
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])+StrToFloat(SL[i+1])));
                               {Zahl vor und nach dem * werden multipliziert und in die Zeile der ersten Zahl geschrieben???} 
                               SL.Delete(i);
                               {Jetzt soll die Zeile des Operators gelöscht werden} 
                               SL.Delete(i);{und die der zweiten Zahl} 
                               {etwas wurde gefunden - fange von vorn an} 
                               i := i-1;
                         end
                      else
                      if SL[i]='-' then
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])-StrToFloat(SL[i+1])));
                               SL.Delete(i);
                               SL.Delete(i);
                               i := i-1;
                         end
                      else
                         i := i + 1;
                  end;

                   
          end;
          end;
      Finally
           
        Result := '';
        For i := 0 to SL.Count - 1 do Result := Result + SL[i];
       
      End;
    Finally
      SL.Free;
    End;
  End;


procedure TForm1.Tabelle;
var X:real;

begin
     X:=1;
     Rechnen.Caption:=ParseAndCalc(X,Formel.text);//Rechnen ist ein Labelfeld, auf dem jetzt '2' stehen sollte
end;


procedure TForm1.BZeichnenClick(Sender: TObject);
begin
     Tabelle;  
end;

Wenn ich jetzt auf den Button klicke kommt die Meldung, X sei kein gültiger Gleitkommawert...
Also wie im Quelltext erwähnt klappt das mit dem Schreiben der SL nicht richtig...

Liebe Grüße!

__________

Sorry wegen den vielen Edits, war ein Quellcode fehler...

himitsu 24. Okt 2009 10:41

Re: Taschenrechner->Graphen zeichenen
 
der String 'X' ist doch auch kein Gleitkommawert!

Du mußt dieses X dann schon durch einen Wert (Zahl) ersetzen, bevor es ans Rechnen geht.
z.B.
Delphi-Quellcode:
'*', '/', '+', '-': Begin
  If SL[SL.Count - 1] = '' Then SL.Delete(SL.Count - 1);
  SL.Add(S[i]);
  SL.Add('');
End;
'X': Begin
  If SL[SL.Count - 1] = '' Then SL.Delete(SL.Count - 1);
  SL.Add({Wert für X});
  SL.Add('');
End;
statt direkt einem String mit dem Wert bei {Wert für X} anzugeben,
kannst du dir auch eine Funktion basteln
und an der Stelle eintragen
Delphi-Quellcode:
funktion GibVariable(Name: String): String;
begin
  ... // hier über den Namen irgendwo, z.B. aus 'ner Liste, den Wert raussuchen
end;
und dann
Delphi-Quellcode:
'X', 'Y', 'Z': Begin // hier gehn dann auch noch andere Namen
  If SL[SL.Count - 1] = '' Then SL.Delete(SL.Count - 1);
  SL.Add(GibVariable(S[i]));
  SL.Add('');
End;

Delphi-Narr 24. Okt 2009 11:13

Re: Taschenrechner->Graphen zeichenen
 
Achso, ich dachte, X könnte man beim Rechnen als Variable setzen... habs jetzt so gemacht, danke!


Edit:

Jetzt kommen ja die Werte raus... Jetzt möchte ich das gerne auf ein Image zeichnen.
Doch im Canvas.MoveTo müssen ja Integerwerte eingetragen werden... Wenn ich jetzt aber 0,1 bekomme, kann ich das logischerweise damit nicht zeichenen.
Gibt's da eine andere Methode?

Die Muhkuh 24. Okt 2009 11:38

Re: Taschenrechner->Graphen zeichenen
 
Musst halt das zu zeichnende Fenster entsprechend anpassen. Bei kleinen Werten so skalieren, dass es wieder zeichenbar ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:05 Uhr.

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