AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Mathe mit Strings (die deutsche StringMatheLib ._. )
Thema durchsuchen
Ansicht
Themen-Optionen

Mathe mit Strings (die deutsche StringMatheLib ._. )

Ein Thema von himitsu · begonnen am 13. Jun 2009 · letzter Beitrag vom 8. Apr 2013
Antwort Antwort
Seite 1 von 10  1 23     Letzte »    
Benutzerbild von himitsu
himitsu
Registriert seit: 11. Okt 2003
Jaaaaaaa, was soll ich sagen ...

» also ich weiß, es ist nicht sonderlich schnell, aber dafür seeeeeeeehr einfach aufgebaut

» es läuft mindestens ab Delphi 7 (drunter hab ich nicht getestet)
und auch für Delphi 2009 ist es geeignet

» man kann die Verwendung der Unit SysUtils abschalten (incl. der Unit Math, da diese die SysUtils verwendet, aber außer Max wird daraus eh nix verwendet)

» Zahlen mit theoretisch über 1 Milliarde Dezimalstellen sind möglich

» die Funktionen sind mit deutschsprachigen Namen versehn

» es steht unter MPL + (L)GPL

» Versionen:
StringMatheLib.pas » Demo 1 » alle Funktionen in einer Klasse verpackt
StringMatheRec.pas » Demo 2 » in einem Record ("MatheString") verpackt und mit Operatoren versehen (ab D2006/TDE)
StringMatheVar.pas » Demo 4 » in einem Variant/"MatheVariant" verpackt und mit Operatoren versehen
StringMatheFloatRec.pas » Demo 3 » wie "MatheString" in einem Record ("MatheStringF") als Festkommazahl
StringMatheParser.pas » Demo 5 » ein kliner Mathe-Parser


» was es derzeit kann ... siehe hier:
Delphi-Quellcode:
// Normalisieren alle ungültigen und zusätzlichen Zeichen entfernen
// Formatieren -
//
// Vergleich -
// Vergleich -
// istPositiv -
// istNegativ -
// istGerade -
// istUngerade -
// gibVorzeichen -
// Dezimalstellen -
//
// Summe r = a + b
// Differenz r = a - b
// Plus1 a = a + 1 oder inc(a)
// Minus1 a = a - 1 oder dec(a)
// Negieren a = -a
// Absolut if a < 0 then r = -a else r = a
//
// Produkt r = a * b
// Quotient r = a div b
// Modulo r = a mod b
// QuotientModulo r = a div b und m = a mod b
//
// Quadrat r = a * a oder r = a ^ 2
// Quadratwurzel r = a ^ 1/2
// Quadratwurzel r = a ^ 1/2 und m = a - (a ^ 1/2)
// Potenz r = a ^ b
// Potenz10 r = 10 ^ b
//
// Quotient2 r = a div 2
// Produkt10 r = a * 10^b
// Quotient10 r = a div 10^b
// Modulo10 r = a mod 10^b
// QuotientModulo10 r = a div 10^b und m = a mod 10^b
//
// SummeModulo r = (a + b) mod m
// DifferenzModulo r = (a - b) mod m
// ProduktModulo r = (a * b) mod m
// PotenzModulo r = (a ^ b) mod m
//
// Zufall r = Random(von, bis)

Type MatheString = Type AnsiString;
  TVergleich = (vUngleich, vKleiner, vKleinerGleich, vGleich, vGroesserGleich, vGroesser);

TMathe = Class
  Property ImmerNormalisieren: Boolean Read _ImmerNormalisieren Write _ImmerNormalisieren;

  Function Normalisieren (a: String): String;
  Function Formatieren (a: String; TausenderPunkte, ImmerMitVorzeichen: Boolean; Mindestlaenge: Integer = 0): String;

  Function Vergleich (a, b: String): TValueRelationship; Overload;
  Function Vergleich (a, b: String; Art: TVergleich): Boolean; Overload;
  Function istPositiv (a: String): Boolean;
  Function istNegativ (a: String): Boolean;
  Function istGerade (a: String): Boolean;
  Function istUngerade (a: String): Boolean;
  Function gibVorzeichen (a: String): Char;
  Function Dezimalstellen (a: String): Integer;

  Function Summe (a, b: String): String;
  Function Differenz (a, b: String): String;
  Procedure Plus1 (Var a: String);
  Procedure Minus1 (Var a: String);
  Procedure Negieren (Var a: String);
  Function Absolut (a: String): String;

  Function Produkt (a, b: String): String;
  Function Quotient (a, b: String): String;
  Function Modulo (a, b: String): String;
  Procedure QuotientModulo (a, b: String; Var Result, Rest: String);

  Function Quadrat (a: String): String;
  Function Quadratwurzel (a: String): String;
  Procedure Quadratwurzel (a: String; Var Result, Rest: String);
  Function Potenz (a, b: String): String;
  Function Potenz10 ( b: String): String;
  Function Potenz10 ( b: Integer): String;

  Function Quotient2 (a: String): String;
  Function Produkt10 (a, b: String): String;
  Function Produkt10 (a: String; b: Integer): String;
  Function Quotient10 (a, b: String): String;
  Function Quotient10 (a: String; b: Integer): String;
  Function Modulo10 (a, b: String): String;
  Function Modulo10 (a: String; b: Integer): String;
  Procedure QuotientModulo10(a, b: String; Var Result, Rest: String);
  Procedure QuotientModulo10(a: String; b: Integer; Var Result, Rest: String);

  Function SummeModulo (a, b, m: String): String;
  Function DifferenzModulo (a, b, m: String): String;
  Function ProduktModulo (a, b, m: String): String;
  Function PotenzModulo (a, b, m: String): String;

  Function zuInteger (a: String): LongInt;
  Function vonInteger (a: LongInt): String;
  Function zuCardinal (a: String): LongWord;
  Function vonCardinal (a: LongWord): String;
  Function zuInteger64 (a: String): Int64;
  Function vonInteger64 (a: Int64): String;

  Function Produkt_langsam (a, b: String): String;
  Procedure QuotientModulo_langsam(a, b: String; Var Result, Rest: String);
  Function Potenz_langsam (a, b: String): String;
End;

» wer die Parameter a und b vor Funktionsaufruf selber normalisiert (also z.B. mindestens einmal nach Eingabe der Werte), der kann .ImmerNormalisieren auf False setzen und es wird dann nicht ständig, beim Starten von Funktionen, durchgeführt ... es wird so also einen Hauch flotter.



Einen Tipp noch zum Schluß: versucht besser nicht eine "größere" Potenz zu berechnen!
(B also nicht zu groß wählen)

Code:
[s]Function TMathe.Potenz(a, b: MatheString): MatheString;
  Begin
    Result := Potenz_langsam(a, b);
  End;[/s]
[edit2] wurde geändert

ChangeLog
[edit]
eine Auto-Refresh-CheckBox in den [berechnen]-Button gelegt

[16.06.2009 v1.0]
mit neuer Lizenz versehen (siehe oben)

[30.06.2009 11°° v1.1]
- einige Optimierungen
- Produkt10, Quotient10, Modulo10 und Co. hinzugefügt
- und der MatheParser kam auch dazu[

[30.06.2009 12°° v1.1]
- der Reinfolgefehler aus Beitrag #55 (Potenzen ala x^y^z) wurde behoben

[30.06.2009 12°° v1.1]
- der Reinfolgefehler aus Beitrag #55 (Potenzen ala x^y^z) wurde behoben

[30.06.2009 14°° v1.1]
- weitere Fehler behoben ... siehe #57+#58
- der Fehler bei den Klammern ist hoffentlich behoben #60

[30.06.2009 15:40 v1.1]
- Fehler im Parser #61

[30.06.2009 16:30 v1.2]
- der Mathe-Parser-Demo um einige Features erweitert (wie den Zwischenspeicher)
- Verwaltung der Konstanten, Funktionen und Operatoren erstellt (im Mathe-Parser)

[01.07.2009 00:30 v1.3]
- ein bissl aufgeräumt
- TMathe.Quadratwurzel, TMathe.PotenzModulo und abhängiges stark beschleunigt
- TMathe.Quotient2 eingeführt r := a div 2 (Grund für vorherigen Punkt)
- Demo6 erstellt = "Fließkomma"-Parser (alles mit # rechnet noch mit "falscher" Nachkommabehandlung)

[01.07.2009 10°° v1.3]
- Anfänge eines UnitTests eingefügt
- XPMan wieder entfernt (#67)
- Fehler behoben (#67 inkompatible Typen)
- TMathe.Produkt nach xZise #67 geändert

[01.07.2009 14²° v1.4]
- einige Dateien von UTF-8 nach Ansi konvertiert
- wegen #72 Version erhöht und alles neu kompiliert bzw. hochgeladen
- weitere Konstanten in die Parser eingefügt

[01.07.2009 14³° v1.4]
- Fehler bei internen Verwaltungsoperatoren behoben ... z.B. Komma wurde nicht erkannt

[01.07.2009 19°° v1.4]
- Verzögerungsfehler in Division entfernt, welcher die Rechenoptimierung abschaltete (#76)
- Vergleichsfunktion optimiert (#76)
- Potenz10, Produkt10 und Quotient10 in StringMatheParserFloat.pas berichtig und freigegeben (Nachkommastellenproblem #76)

[01.07.2009 20°° v1.5]
- Rechenfehler aus #67 behoben

[03.07.2009 12°° v1.5]
- Dezimalstellenfunktion mit Fehlerprüfung versehen und die Anzeiger der Stellen in den Demos etwas umgestellt (siehe #79..#81)

[03.07.2009 21³° v1.6]
- .Normalisieren und .Formatieren überarbeitet (#84)
- etwas aufgeräumt und die "InFile"-Hilfe erweitert
- doch wieder auf Bei Google suchen7zip umgestiegen (ist 60% kleiner)
Miniaturansicht angehängter Grafiken
demo_828.png  
Angehängte Dateien
Dateityp: 7z stringmathelib_131.7z (97,5 KB, 317x aufgerufen)
Dateityp: exe demo5_106.exe (566,0 KB, 165x aufgerufen)
Dateityp: 7z stringmathelib__154.7z (439,3 KB, 192x aufgerufen)
$2B or not $2B
 
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#2
  Alt 14. Jun 2009, 16:41
nur 'ne winzig kleine Änderung

- Potenz wurde richtig eingebaut

- über den Edits wird in Klammern die Anzahl der Dezimalstellen eingeblendet

- so, daß war's auch schon

- ach ja, bei den Potenzen wird eine Warnung angezeigt, ob man wirklich will, wenn der Exponent viel zu groß ist und es seeeeeeeehr lange dauern würde


z.B. 1234567890123456789^50 wird in nur 0,8 Sekunden berechnet
und ergibt ein Ergebnis mit 905 Dezimalstellen

und 1234567890123456789 * 987654 braucht nur 0,04 Millisekunden
  Mit Zitat antworten Zitat
qwertz543221
 
#3
  Alt 14. Jun 2009, 19:22
nöö üüüberhaupt nicht schnell(achtung: ironie!!)

das ist richtig toll, was du da produziert hast. so gut hätte ich das doch nie hinbekommen.

genau das was ich gebraucht habe

THX
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#4
  Alt 14. Jun 2009, 19:56
Also gegen mein altes Hier im Forum suchenTBigInt sollte dieses um Längen langsamer arbeiten (auch wenn ich noch keinen Vergleich der beiden Typen angestellt hab) und vorallem bei den "höheren" Funktionen kommt selbst TBigInt nicht gegen sowas Hochoptimiertes wie das DEC an.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#5
  Alt 15. Jun 2009, 00:17
kleines Update mit Operatoren ... siehe Demo2
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

 
Delphi 10.4 Sydney
 
#6
  Alt 15. Jun 2009, 10:52
Hi himitsu,

Hut ab! Klasse Unit, die ich auch sofort für ein altes Zahlenkonvertier-Problem in einem meiner Programme einsetzen kann.

Ich habe mich nur gefragt, warum du Mathestring auf AnsiString typecastes und in ein paar Funktionen explizit AnsiStrings und AnsiChars benutzt und nicht generell String und Char?
Ich habe das mal umgestellt und soweit ich das übersehen kann und getestet habe, läufts dann auch mit Unicode-Strings unter D2009.

Interesse an den geänderten Sourcen?

Gruß,
Stefan
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#7
  Alt 15. Jun 2009, 11:10
Also die neue Operator-Unit hatte ich auf MatheRString ausgelegt und nur die externen Zuweisungen als AnsiString, WideString und Int64 vorgesehn ... beim anderen hatte ich in Bezug auf Delphi2009 es MatheString genannt.

Wenn ich da String und Char nehme, ist erstmal der Speicherverbrauch doppelt so hoch, was aber erstmal egal ist.
Aber schlimmer ist, daß man bei String/UnicodeString in D2009 kein IN [...] mehr verwenden kann.

Drum wurde alles "explizit" als AnsiString/MatheString definiert.


In der StringMatheLib.pas sollte aber, bist auf das Trim für D2009 (da es dort blöder Weise keine überladene Ansi-Verion gibt) alles als MatheString definiert.


Und das "MatheString" hatte ich so genommen, damit es besser auffällt und man nicht so ausversehn mal mit AnsiString/WideString/UnicodeString/String in Konflikt kommt und man nimmer weiß, was man nehmen soll,
außerdem paßt der Name so besser zur Record-Version
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

 
Delphi 10.4 Sydney
 
#8
  Alt 15. Jun 2009, 11:17
OK, danke für die Erklärungen.

Anbei ein kleiner Code-Schnipsel als Ersatz für CharInSet unter Delphi<=2007:

Delphi-Quellcode:
{$IFNDEF COMPILER12_UP}
function CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean;
begin
  Result := C in CharSet;
end;
{$ENDIF !COMPILER12_UP}
Edit: Der Define COMPILER12_UP kommt aus der Jedi.inc, kann aber auch direkt ersetzt werden.
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#9
  Alt 15. Jun 2009, 11:34
klappt nicht ganz ... die "umständliche" Variante ist eher:
Delphi-Quellcode:
function CharInSet(C: Char; const CharSet: TSysCharSet): Boolean;
begin
  Result := (C <= #$00FF) and (AnsiChar(Word(C)) in CharSet);
end;
Und für diese Funktion 32 Byte für ein TSysCharSet ständig hin- und herzukopieren?
(hätt das dann eher direkt in die ganzen Abfragen eingebaut, da so Delphi dann optimieren kann)

Das wollte ich dem Code nicht antun, drum bin ich beim ANSI geblieben.
Aber mal sehn, vielleich finde ich ja noch was "Schönes".
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

 
Delphi 10.4 Sydney
 
#10
  Alt 15. Jun 2009, 11:45
Eh... Die Funktion ist doch für alle Delphis 2007 und älter. Da ist ein Char=AnsiChar = immer <=$FF oder?
Stefan
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 10  1 23     Letzte »    


Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 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