![]() |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
ganz vorne im Ersten, also
![]() das ist das Gute an der OpenSource- und FreeWare-Sparte ... hier gibt es kein 24-Stunden-Limit und man kann immer fleißig alles in den Anfangspost einfügen bzw. ändern und keiner muß suchen :angel: Und ich glaub aktuell gibt es eh nur in dem 1. Post eine Version zum Downloaden, da ich die anderen Zwischenversionen aus den Beiträgen gelöscht hab ... braucht ja keiner mehr und die DP wird etwas entlastet. |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Moin,
kann es sein, dass "Dezimalstellen" nicht ganz in Ordnung arbeitet? Also "+12" würde 3 zurückgeben, während "-12" nur 2 zurückgibt ebenso wie "12" (ohne das +). Wobei ich jetzt nicht sicher bin, ob das immer auftritt, oder nur, wenn die automatische Normalisierung deaktiviert ist.
Delphi-Quellcode:
Statt "istNegativ" müsste abgefragt werden, ob das erste Zeichen ein Vorzeichen ist.
Function TMathe.Dezimalstellen(a: String): Integer;
Begin Try If _ImmerNormalisieren Then _Normalisieren(a); Result := Length(a); If istNegativ(a) Then Dec(Result); Except Result := -1; End; End; Also stattdessen:
Delphi-Quellcode:
MfG
If Ord(a[Length(a)]) in [Ord('+'), Ord('-')] Then Dec(Result);
xZise |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Also im Prinzip sollte es so funktionieren - bei ImmerNormalisieren sowieso
Ich hab es eigentlich abschaltbar gemacht, falls man mit mehreren gekoppelten Berechnungen sich dieses sparren möchte, aber da sollte man dann vorher die "Eingabewerte" selber einmal manuell Normalisieren. Ansonsten hätte nicht nur die Dezimalstellenfunktion einige Probleme :nerd:
Delphi-Quellcode:
PS: unnormalisiert wäre z.B. '-++-+---+-2' eine gültige Zahl :roll:
Mathe.ImmerNormalisieren := False;
// Werte einlesen a := Mathe.Normalisieren(Edit1.Text); b := Mathe.Normalisieren(Edit2.Text); c := Mathe.Normalisieren(Edit3.Text); // viel berechnen r := Mathe.Summe(a, b); r2 := Mathe.Diverenz(r, b); r := Mathe.Potent(r2, r); ... oder was auch immer ... // Ergebnis ausgeben Edit4.Text := Mathe.Formatieren(r); und was möge wohl passieren, wenn als Eingabestring mal ein '' durchkäme :shock: ansonsten steht schon seit langem sowas im ersten Post und beim nächsten Update auch in der kleinen Inlinehile in der StringMatheLib.pas :zwinker: Zitat:
|
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
ChangeLog [03.07.2009 21³° v1.6] - .Normalisieren und .Formatieren überarbeitet (#84) - etwas aufgeräumt und die "InFile"-Hilfe erweitert - doch wieder auf ![]() das Normalisieren wurde um ein paar Stringoperationen erleichtert und anderes wurde zusammengefaßt, außerdem wird keine bereits normalisierte Nummer mehr bearbeitet (vorallem wurde negativen Werten intern kurz das Minus gemopst und am Ende ein Neues verpaßt :freak: ) ich hoff ja für die Potenz noch eine "einfache" Lösung zu finden, damit diese etwas flotter wird 1234567890123456789^100 in einer Sekunde, ^200 in 4s und ^500 braucht gleich mal 17s |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Hi,
im folgenden ein paar Erweiterungen der StringMatheLib für die Konvertierung von großen Zahlen in verschiedenen Zahlensystemen. 1. Aus beliebigen Zahlensystemen zur Basis N ins Dezimal-System
Delphi-Quellcode:
2. Aus dem Dezimal-System in beliebige Zahlensysteme zur Basis N
function ZahlNToINT(const ZahlN, BasisN: string): string;
Delphi-Quellcode:
3. und die Verallgemeinerung von Basis N in Basis M
function INTToZahlN(const Zahl10, BasisN: string): string;
Delphi-Quellcode:
Ein paar benötigte Hilfefunktionen sind auch noch dabei:
function ZahlNToZahlM(const ZahlN, BasisN, BasisM: string): string;
1. Bereinigen des Zahlstrings von nicht erlaubten Zeichen
Delphi-Quellcode:
2. (private) Funktionen zum Zuweisen Werten zu Ziffern und umgekehrt
function ZahlNBereinigen(const ZahlN, BasisN: string): string;
Delphi-Quellcode:
Augerufen werden die public functions so:
function _GetZahl(const Value: Char): Integer;
function _GetZeichen(const Number: Integer): String;
Delphi-Quellcode:
uses
StringMatheLib; var Mathe: TMathe; procedure TForm1.bBaseNTo10Click(Sender: TObject); begin eBaseN.Text:=Mathe.ZahlNBereinigen(eBaseN.Text, IntToStr(JvSEBaseN.AsInteger)); //CleanUp Zahl-String zur Basis N eBase10.Text:=Mathe.ZahlNToINT(eBaseN.Text, IntToStr(JvSEBaseN.AsInteger)); end; procedure TForm1.bBase10ToMClick(Sender: TObject); begin eBase10.Text:=Mathe.ZahlNBereinigen(eBase10.Text, '10'); //CleanUp Zahl-String zur Basis N eBaseM.Text:=Mathe.INTToZahlN(eBase10.Text, IntToStr(JvSEBaseM.AsInteger)); end; Hier die Änderungen an der letzten Version der StringMatheLib.pas [v1.6]:
Delphi-Quellcode:
Gruß,
interface
... TMathe = class private ... function _GetZahl(const Value: Char): Integer; function _GetZeichen(const Number: Integer): String; public ... function ZahlNBereinigen(const ZahlN, BasisN: string): string; function ZahlNToINT(const ZahlN, BasisN: string): string; function INTToZahlN(const Zahl10, BasisN: string): string; function ZahlNToZahlM(const ZahlN, BasisN, BasisM: string): string; end; implementation ... function TMathe._GetZahl(const Value: Char): Integer; //Char in Integer umwandeln (z.B. 'A' in 10) //'012..89ABC...XYZ':=Array[0..36]; begin Result := Ord(Value); if ((Result >= Ord('0')) and (Result <= Ord('9'))) then //Zahlen von 0 bis 9 Result := Result - Ord('0') else if ((Result >= Ord('A')) and (Result <= Ord('Z'))) then //Buchstaben von A bis Z Result := Result - (Ord('A') - 10) else Result := -1; end; function TMathe._GetZeichen(const Number: Integer): String; //Integer in Char umwandeln (z.B. 10 in 'A') //Array[0..36]:='012..89ABC...XYZ'; begin if ((Number >= 0) and (Number <= 9)) then //Zahlen von 0 bis 9 Result := Chr(Number + Ord('0')) else if ((Number >= 10) and (Number <= 36)) then //Buchstaben von A bis Z Result := Chr(Number + (Ord('A') - 10)) else Result := ''; end; function TMathe.ZahlNBereinigen(const ZahlN, BasisN: string): string; //Zahl-String zur Basis N von allen Zeichen bereinigen, die nicht zwischen // '0' und Chr(N) liegen var i: Integer; ZahlN_: string; begin ZahlN_:=Uppercase(ZahlN); for i := Length(ZahlN_) downto 1 do //Rückwärts da sonst mehrfach hintereinander //auftretende nicht erlaubte Zeichen nicht korrigiert würden begin if ((_GetZahl(ZahlN_[i]) < 0) or (_GetZahl(ZahlN_[i]) >= StrToInt(BasisN))) then Delete(ZahlN_, i, 1); end; Result:=ZahlN_; end; function TMathe.ZahlNToINT(const ZahlN, BasisN: string): string; //Implementiert nach Horner's Algorithmus ohne Potenz-Multiplikation: //Zahl zur Basis N mit n Ziffern: x(1)x(2)x(3)...x(n-1)x(n) //=> Zahl zur Basis 10 := [(((x(1) * N) + x(2) ) * N + x(3) ) * N ... upto x(n-1)] + x(n) var i: Integer; Zahl10: string; ZahlN_: string; begin ZahlN_:=ZahlNBereinigen(ZahlN, BasisN); //CleanUp Zahl-String zur Basis N Zahl10:='0'; try for i := 1 to Length(ZahlN_) do begin Zahl10:=Summe(Produkt(Zahl10, BasisN), IntToStr(_GetZahl(ZahlN_[i]))); //Vorsicht: GetZahl kann -1 werden! //Wird durch ZahlNBereinigen verhindert! end; except Zahl10:=''; end; Result:=Zahl10; end; function TMathe.INTToZahlN(const Zahl10, BasisN: string): string; var Zahl10_: string; ZahlN: string; Rest: string; begin Zahl10_:=ZahlNBereinigen(Zahl10, '10'); //CleanUp Zahl-String zur Basis 10 ZahlN:=''; try repeat Rest := Modulo (Zahl10_, BasisN); Zahl10_ := Quotient(Zahl10_, BasisN); ZahlN := _GetZeichen(StrToInt(Rest)) + ZahlN; //Bei zu großem Rest kommt '' zurück until Zahl10_='0'; except ZahlN:=''; end; Result:=ZahlN; end; function TMathe.ZahlNToZahlM(const ZahlN, BasisN, BasisM: string): string; begin Result:=INTToZahlN(ZahlNToINT(ZahlN, BasisN), BasisM); end; Stefan |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Ich halte ein heimliches Bereinigen von Eingaben (außer trim) für nicht hilfreich. Wenn man es denn haben will, sollte es mM via Property analog ImmerNormalisieren schaltbar sein, default nicht bereinigen.
|
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Damit die neuen Funktionen auch ohne die SysUtils klarkommen, sind noch ein paar Änderungen nötig:
- StrToInt ersetzt durch zuInteger64 - IntToStr ersetzt durch vonInteger64 - SysUtils.Uppercase konditional ersetzt durch lokales _Uppercase Gruß, Stefan
Delphi-Quellcode:
interface
... private ... function _GetZahl(const Value: Char): Integer; function _GetZeichen(const Number: Integer): String; {$IFNDEF VerwendeUnitSysUtils} function _Uppercase(const input: string): string; {$ENDIF} implementation ... function TMathe._GetZahl(const Value: Char): Integer; //Char in Integer umwandeln (z.B. 'A' in 10) //'012..89ABC...XYZ':=Array[0..36]; begin Result := Ord(Value); if ((Result >= Ord('0')) and (Result <= Ord('9'))) then //Zahlen von 0 bis 9 Result := Result - Ord('0') else if ((Result >= Ord('A')) and (Result <= Ord('Z'))) then //Buchstaben von A bis Z Result := Result - (Ord('A') - 10) else Result := -1; end; function TMathe._GetZeichen(const Number: Integer): String; //Integer in Char umwandeln (z.B. 10 in 'A') //Array[0..36]:='012..89ABC...XYZ'; begin if ((Number >= 0) and (Number <= 9)) then //Zahlen von 0 bis 9 Result := Chr(Number + Ord('0')) else if ((Number >= 10) and (Number <= 36)) then //Buchstaben von A bis Z Result := Chr(Number + (Ord('A') - 10)) else Result := ''; end; {$IFNDEF VerwendeUnitSysUtils} function TMathe._Uppercase(const input: string): string; var i: Integer; begin Result:=input; for i := 1 to Length(Result) do begin if Result[i] in ['a'..'z'] then result[i]:=chr(Ord(result[i]) - 32); end; end; {$ENDIF} function TMathe.ZahlNBereinigen(const ZahlN, BasisN: string): string; //Zahl-String zur Basis N von allen Zeichen bereinigen, die nicht zwischen // '0' und Chr(N) liegen var i: Integer; ZahlN_: string; begin {$IFDEF VerwendeUnitSysUtils} ZahlN_:=Uppercase(ZahlN); {$ELSE} ZahlN_:=_Uppercase(ZahlN); {$ENDIF} for i := Length(ZahlN_) downto 1 do //Rückwärts da sonst mehrfach hintereinander //auftretende nicht erlaubte Zeichen nicht korrigiert würden begin if ((_GetZahl(ZahlN_[i]) < 0) or (_GetZahl(ZahlN_[i]) >= zuInteger64(BasisN))) then Delete(ZahlN_, i, 1); end; Result:=ZahlN_; end; function TMathe.ZahlNToINT(const ZahlN, BasisN: string): string; //Implementiert nach Horner's Algorithmus ohne Potenz-Multiplikation: //Zahl zur Basis N mit n Ziffern: x(1)x(2)x(3)...x(n-1)x(n) //=> Zahl zur Basis 10 := [(((x(1) * N) + x(2) ) * N + x(3) ) * N ... upto x(n-1)] + x(n) var i: Integer; Zahl10: string; ZahlN_: string; begin ZahlN_:=ZahlNBereinigen(ZahlN, BasisN); //CleanUp Zahl-String zur Basis N Zahl10:='0'; try for i := 1 to Length(ZahlN_) do begin Zahl10:=Summe(Produkt(Zahl10, BasisN), vonInteger64(_GetZahl(ZahlN_[i]))); //Vorsicht: GetZahl kann -1 werden! //Wird durch ZahlNBereinigen verhindert! end; except Zahl10:=''; end; Result:=Zahl10; end; function TMathe.INTToZahlN(const Zahl10, BasisN: string): string; var Zahl10_: string; ZahlN: string; Rest: string; begin Zahl10_:=ZahlNBereinigen(Zahl10, '10'); //CleanUp Zahl-String zur Basis 10 ZahlN:=''; try repeat Rest := Modulo (Zahl10_, BasisN); Zahl10_ := Quotient(Zahl10_, BasisN); ZahlN := _GetZeichen(zuInteger64(Rest)) + ZahlN; //Bei zu großem Rest kommt '' zurück until Zahl10_='0'; except ZahlN:=''; end; Result:=ZahlN; end; function TMathe.ZahlNToZahlM(const ZahlN, BasisN, BasisM: string): string; begin Result:=INTToZahlN(ZahlNToINT(ZahlN, BasisN), BasisM); end; |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Zitat:
Delphi-Quellcode:
Über die Fehlerbehandlung (Exception-Raising) müsste man dann nochmal nachdenken...
function TMathe.ZahlNToINT(const ZahlN, BasisN: string): string;
... begin if _ImmerNormalisieren then begin ZahlN_:=ZahlNBereinigen(ZahlN, BasisN); //CleanUp Zahl-String zur Basis N end; ... end; function TMathe.INTToZahlN(const Zahl10, BasisN: string): string; ... begin if _ImmerNormalisieren then begin Zahl10_:=ZahlNBereinigen(Zahl10, '10'); //CleanUp Zahl-String zur Basis 10 end; ... end; |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Zitat:
Gruß Gammatester |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Delphi-Quellcode:
der Defaultstring reicht bis Basis 64
Const BStellen = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-';
Function TMathe.vonBasisN(ZahlN, BasisN: String; Stellen: String = BStellen): String; Var i, i2: Integer; Begin Result := '0'; For i := 1 to Length(ZahlN) do Begin i2 := Pos(ZahlN[i], BStellen) - 1; If i2 < 0 Then System.{$IFDEF PROCEDURE_ERROR}Error(reRangeError){$ELSE}RunError(201){$ENDIF}; Result := Summe(Produkt(Result, BasisN), vonInteger64(i2)); End; End; Function TMathe.zuBasisN(Zahl10, BasisN: String; Stellen: String = BStellen): String; Var i: Integer; Rest: String; Begin Result := ''; Repeat QuotientModulo(Zahl10, BasisN, Zahl10, Rest); i := zuInteger(Rest); If i >= Length(BStellen) Then System.{$IFDEF PROCEDURE_ERROR}Error(reRangeError){$ELSE}RunError(201){$ENDIF}; Insert(BStellen[i + 1], Result, 1); Until Zahl10 = '0'; End; Function TMathe.BasisNzuM(ZahlN, BasisN, BasisM: String; Stellen: String = BStellen): String; Begin Result := zuBasisN(vonBasisN(ZahlN, BasisN), BasisM); End;
Delphi-Quellcode:
falls Keiner was einzuwenden hat, bau ich's bei Gelegenheit mit ein
s := '123456789';
s := zuBasisN(s, '2'); WriteLn(s); // s = '111010110111100110100010101'; s := vonBasisN(s, '2'); WriteLn(s); // s = '123456789' s := zuBasisN(s, '16'); WriteLn(s); // s = '75BCD15'; s := vonBasisN(s, '16'); WriteLn(s); // s = '123456789' s := zuBasisN(s, '64'); WriteLn(s); // s = '7MyqL'; s := vonBasisN(s, '64'); WriteLn(s); // s = '123456789' |
Re: Mathe mit Strings (die deutsche StringMatheLib ._. )
Moin Stefan,
da ist glaub ich ein Fehler drinne: Zitat:
Also etwas wie sowas:
Delphi-Quellcode:
function TMathe.ZahlNBereinigen(const ZahlN, BasisN: string): string;
//Zahl-String zur Basis N von allen Zeichen bereinigen, die nicht zwischen // '0' und Chr(N) liegen var ZahlN_: string; i, Ziffer, BasisInt, StartZeichen : Integer; begin ZahlN_:=Uppercase(ZahlN); if Ord(a[1]) in [Ord('+'), Ord('-')] then StartZeichen := 2 else StartZeichen := 1; BasisInt := StrToInt(BasisN); // Rückwärtige Schleife, da der String hinter der aktuellen Position // verkürzt wird for i := Length(ZahlN_) downto StartZeichen do begin Ziffer := _GetZahl(ZahlN_[i]); if (Ziffer < 0) or (Ziffer >= BasisInt) then Delete(ZahlN_, i, 1); end; Result:=ZahlN_; end; Zitat:
Abgesehen davon müsste es eigentlich statt "a[Length(a)]" nur "a[1]" heißen. MfG xZise |
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
Hallo himitsu,
über die Festtage habe ich mir Deinen MatheParser angeguckt und finde ihn sehr gelungen. Bei kleinen Test ist mir aufgefallen, dass das Potenzieren mit "^" nicht so richtig funktioniert. Zum einem muß wohl in
Delphi-Quellcode:
der Operator von #^ zu ^ verändert werden.
Constructor TMatheParserF.Create;
Zum anderen läuft er sich in
Delphi-Quellcode:
aber irgendwie fest. Die Loop-Schleife findet scheinbar irgenwie keinen Ausstieg. Vielleicht muß diese '1' normalisiert werden?
Function TMathe.Potenz
In dem Demo5 tritt der Fehler nicht auf. Gibt es schon eine Korrektur? Gruss Jens |
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
ICh weiß der Beitrag ist schon alt aber ich ärgere mich seit gestern mit einem Problem und diese unit hier hat das gleiche Problem.
Kann mir bitte jemand erklären warum matheparser anscheinend ein Problem hiermit haben: (25-20-4) Ergebnis ist dann 6 Aber warum?? Gebe ich das so in den Windowsrechner ein kommt 1 raus. Andererseits kann Delphi aber dies richtig rechnen: (9*2/2-2)ebenso wie dies (5+3+1) dies kann er wieder nicht berechnen: (5-3-1) da bekommt er 3 raus. Kann mir das bitte jemand erklären? Danke! |
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
Zitat:
|
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
Beim einen Schritt stimmt es ab dem nächsten dann einfach nicht mehr. Das lässt sich nicht debuggen. Hat auch nicht unbedingt was mit dieser Lib zu tun, scheint eher ein grundsätzliches Problem zu sein. Vlt. antwortet noch jemand der das erklären kann.
|
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
Nach meinem Post habe ich mich länger mit Mathparsern, die es in der Delphi-Welt gibt, beschäftigt. Es gibt von diesen ca. 1 Mio., aber keinen der richtig funktioniert. Das kommt wahrscheinlich daher, dass alle heiß sind sich daran zu probieren dann aber nicht zu Ende gebracht werden.
Gefunden habe ich 2 Parser, die etwas taugen: ![]() ![]() Wobei -man glaubt es kaum- der Parser aus Cindy ca. 30% schneller ist als der Parser10, der als schnell gilt. |
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
Zitat:
|
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
Vielleicht ein F8 statt F7 Problem ...
|
AW: Mathe mit Strings (die deutsche StringMatheLib ._. )
@Jens01,
vielen Dank für die Empfehlung des cymathparser!! Dieser funktioniert tatsächlich einwandfrei. Klasse! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz