|
Registriert seit: 29. Aug 2009 Ort: Duisburg 437 Beiträge Delphi 2007 Professional |
#10
Ich habe das auch gemacht (also decimal:=0), klappt aber nicht richtig (rechnet falsch)...
Bei 1,1 * 9 kommt nicht 9,9 raus sondern 0,4 oder so etwas... Ich habe mal einen komplett neuen geschrieben, der klappt jetzt auch... Der schreibt den Term nach Zahlen und Operatoren sortiert in eine Liste, fügt oder löscht falsche Rechenzeichen (hinzu), geht dann den Term von HINTEN durch und sucht nach Klammern, löst diese auf. Dann normal nach Potemzen suchen und auflösen und dann Punkt vor Strich. Ich hätte mir zwar das normale auflösen (nach den Klammern) sparen können, indem ich einfach Klammern aufrufe, aber aus Testzwecken habe ich das stehen lassen (um die Zehnmilliarden Fehler beim durchgehen zu umgehen). Hier mein Ergebnis:
Delphi-Quellcode:
Viele Grüße und viel Spaß damit
function TermTOFloat(Term:string):real;
function Klammern(T:string):string; Var SL: TStringList; i: Integer; S: string; Begin {Falls das erste Zeichen ein Rechenzeichen wie + oder - ist, so wird eine Null eingefügt, um die Rechnung fortzusetzen (Beim Rechnen würde sonst ein Fehler auftreten)} S:=T; case S[1] of '+','-': begin insert('0',S,1); end; {Die Rechenzeichen * und / werden gelöscht} '*','/': begin Delete(S,1,1); end; end; //Rechenzeichen am Ende werden gelöscht case S[Length(S)] of '+','-','*','/': begin Delete(S,Length(S),1); end; end; 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; '*', '/', '+', '-','^': Begin If SL[SL.Count - 1] = '' Then Begin // eine leere Zeile kommt vor, wenn mehrere Operatoren // hintereinander liegen, z.B. bei '1*+2' bzw. '1 * +2' SL.Delete(SL.Count - 1); End; SL.Add(S[i]); SL.Add(''); End; ' ': ; // ignoriere Leerzeichen Else Raise Exception.CreateFmt('Ungültiges Zeichen "%s" gefunden.', [S[i]]); End; {Ab hier wird gerechnet} begin begin i:=0; while i < SL.Count do begin if SL[i]='^' then begin SL[i-1]:=(FloatToStr(Power(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 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; 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 := SL[0]; end; Finally SL.Free; End; end; Var SL: TStringList; i,p,j,a: Integer; S,tmp: string; Begin Result:=0; {Falls das erste Zeichen ein Rechenzeichen wie + oder - ist, so wird eine Null eingefügt, um die Rechnung fortzusetzen (Beim Rechnen würde sonst ein Fehler auftreten)} S:=Term; case S[1] of '+','-': begin insert('0',S,1); end; {Die Rechenzeichen * und / werden gelöscht} '*','/': begin Delete(S,1,1); end; end; //Rechenzeichen am Ende werden gelöscht case S[Length(S)] of '+','-','*','/': begin Delete(S,Length(S),1); end; end; //Klammern durchsuchen und prüfen, ob ein Rechenzeichen davor steht, sonst * einfügen for i:=2 to Length(S) do begin if (S[i]='(') and (pos(S[i-1],'+-*/')=0) then insert('*',S,i); end; 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; '*', '/', '+', '-','^','(',')': Begin If SL[SL.Count - 1] = '' Then Begin // eine leere Zeile kommt vor, wenn mehrere Operatoren // hintereinander liegen, z.B. bei '1*+2' bzw. '1 * +2' SL.Delete(SL.Count - 1); End; SL.Add(S[i]); SL.Add(''); End; ' ': ; // ignoriere Leerzeichen Else Raise Exception.CreateFmt('Ungültiges Zeichen "%s" gefunden.', [S[i]]); End; //Klammern suchen und auflösen i:=SL.count-1; while i>=0 do begin if SL[i]='(' then begin p:=i; tmp:=''; j:=p+1; while (SL[j]<>')') do begin tmp:=tmp+SL[j]; j:=j+1; if j=SL.count then break; end; if j=SL.count then j:=j-1; tmp:=Klammern(tmp); SL[p]:=tmp; //Löschen a:=p+1; for p:=P+1 to j do begin SL.Delete(a); end; end; i:=i-1; end; tmp:=''; for i:=0 to SL.count-1 do tmp:=tmp+SL[i]; {Ab hier wird gerechnet} begin begin i:=0; while i < SL.Count do begin if SL[i]='^' then begin SL[i-1]:=(FloatToStr(Power(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 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; 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 tmp:=SL[0]; Try Result := StrToFloat(SL[0]); except Result:=0; end; end; Finally SL.Free; End; end; ![]() Geändert von Delphi-Narr ( 5. Sep 2010 um 10:44 Uhr) |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |