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 6 von 10   « Erste     456 78     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
 
gammatester
 
#51
  Alt 30. Jun 2009, 09:17
Bug:
Code:
StringMatheLib.pas(810)
StringMatheParser.pas(163) Error: Undeclared identifier: 'SummeModulo'
StringMatheParser.pas(169) Error: Undeclared identifier: 'DifferenzModulo'
StringMatheParser.pas(491)
ParserU.pas(5) Fatal: Could not compile used unit 'StringMatheParser.pas'
Wahrscheinlich benutzt Du ein neuere Version von StringMatheLib, die nicht dabei ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#52
  Alt 30. Jun 2009, 09:50
ja, die Beiden sind neu
Delphi-Quellcode:
* Function TMathe.SummeModulo(a, b, m: String): String;
    Begin
      Result := Modulo(Summe(a, b), m);
    End;

  Function TMathe.DifferenzModulo(a, b, m: String): String;
    Begin
      Result := Modulo(Differenz(a, b), m);
    End;
wollte eigentlich nur noch schnell die Units aufräumen und etwas optimieren, bevor ich alles hochlade

und ups , blödes Copy&Paste
  Mit Zitat antworten Zitat
gammatester
 
#53
  Alt 30. Jun 2009, 10:42
Bevor Du optimierst, solltest Du ein grundsätzliches Problem bei dieser Art Parser beseitigen:

Bei Ausdrücken der Art <Term> ::= <Factor1> 'mod' <Factor2> hat man bei Langzahlbibliotheken immer das Problem, daß Factor1 nicht normal ausgewertet werden sollte, sondern wenn der 'mod'-Operator benutzt wird, sollte zuerst Factor2 ausgewertet werden und dann Factor1 via Modulararithmetik mit Modul Factor2. Sonst wirst Du zB praktisch nie eine RSA-Verschlüsselung bzw PotenzMod-Operation mit Nicht-Spielzeugzahlen durchführen können.

Gammatester

PS: Dies ist auch ein Grund, warum Operatorüberladen bei mod eine kitzlige Sache ist, vgl. Hagen's Beitrag
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#54
  Alt 30. Jun 2009, 10:52
Falls du sowas meinst R := A ^ B mod C:
Da ich bei den Operatoren die Reinfolge der Operationen nicht beeinflussen kann, wird hier immer erst A ^ B gerechnet und dann erst (A^B) mod C,
aber dafür ist die Lib Selber erstmal als Klasse ausgelegt, wo es die Funktion ProduktModulo gibt.

Die Operatoren ala MOD sind ja nur als "eingeschränktes" Zusatzmodul verfügbar.
  Mit Zitat antworten Zitat
gammatester
 
#55
  Alt 30. Jun 2009, 11:48
Ja das meinte ich. Allerdings ist diese Nicht-Implementation doch ein wenig einschränkend für einen Langzahl-Rechner. Aber nun zu etwas Positivem, nämlich ein Bug, der beseitigt werden kann:

2^3^4 wird als (2^3)^4 geparst und nicht, wie es mathematisch richtig wäre, als 2^(3^4).
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#56
  Alt 30. Jun 2009, 11:52
so, hab mal den 1. Beitrag editiert und alles Neue mit eingefügt.

zusätzlich wurden der Parser und die "Grund"Lib um folgende Funktionen erweitert:
Code:
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
hier wird dann nix gerechnet, da Operationen in 10-Potenzen ja einfach und vorallem schnell, durch Anhängen von '0'en und durch einfaches Umkopieren erledigt werden können.

ich hab jetzt allerdings noch nicht alles getestet, aber ich hoff einfach mal es funktioniert
diese Funktionen werden dann auch demnächst in die Normalisierungsfunktion mit einfließen (zumindestens teilweise)


ach ja, falls sich wer wundert: "Normalisieren" entfernt einfach alle ungültigen Zeichen ... aus "-c1a0-" wird also "-10" ... ich glaub da werd' ich demnächst noch was dran ändern.

[add]
es ist doch implementiert ... du mußt da einfach nur die Funktion nehmen und nicht die Operatoren

und was den behebbaren Bug betrifft, da müßte es doch reichen, wenn ich die Auswertung einfach rückwärts angeh
(wird also hoffentlich beim nächsten Update behoben sein)

[edit]
Bug ist behoben (siehe #1)

[edit2]
jetzt mekert er bei (2^3)^4 oder ging das schon immer nicht
  Mit Zitat antworten Zitat
gammatester
 
#57
  Alt 30. Jun 2009, 12:36
Wahrscheinlich bin zu blöd oder Dein Teil mag mich nicht. Wie gebe ich eine Funktion ein? PotenzModulo(????). Aber auch Summe(1,2) mault: Zahl erwartet. Summe( 1 2) mault: Komma erwartet ...

Produkt10('12', 4) oder Produkt10('12', '4') ergeben immer noch 12, statt 4 kannst Du auch 7 oder 42 einsetzen.

Da der Code nicht funktioniert, kann ich auch nicht testen ob Produkt10('0',4) = '0000' ist. Nach Quellcodelage schon. Also Test auf 0 bevor 'geshiftet' wird.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#58
  Alt 30. Jun 2009, 12:51
ups, das mit Summe und Co. ist ein kleiner Fehler im Parser

so geht es
Code:
Summe(1 , 2)
Problem, das Komma wird mit zur Zahl genommen (also 1,2 aka 1.2 in Pascal ) ... war blöd, da es sich hier doch eh nur um eine Ganzezahllib handelt
und später wird richtig erkannt, daß in der Zahl kein Komma vorkommen dürfte

[edit]
einfach das ',' aus der Whileschleife entfernen und schon sollte es gehn
Delphi-Quellcode:
Function TMatheParser.Trenne(Var Liste: TMatheParserListe; Const S: String; i: Integer): Integer;
...
        End Else If S[i] in ['0'..'9'] Then Begin
          i2 := i;
          While S[i2] in ['0'..'9', '.'] do Inc(i2);
Dennoch hab ich vermutlich irgendwo in der Klammerbehandlung ein Fehler, welcher z.B. (2^3)^4 durchdrehn läßt und einen String zerschießt.
  Mit Zitat antworten Zitat
gammatester
 
#59
  Alt 30. Jun 2009, 13:01
So weit OK bei den Funktionen. Das Produkt10-Problem betrifft allerdings die StringMatheLib und bleibt somit bestehen (allerdings kann man jetzt mit dem korrigierten Parser schneller feststellen, daß was nicht stimmt )
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#60
  Alt 30. Jun 2009, 13:58
das Produkt10(0,4) sollte jetzt gehn

beim Füllen mit '0' war der PChar etwas zu hoch (das Inc(P) mußte nach dem P^:='0' rein)
und der Fall bezüglich a='0' wird nun auch beachtet.


und bezüglich (2^3)^4:
Zitat:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Demo5.exe ist eine Exception der Klasse EOutOfMemory mit der Meldung 'Zu wenig Arbeitsspeicher' aufgetreten.
---------------------------
Anhalten Fortsetzen Hilfe
---------------------------
Zitat:
---------------------------
Demo5
---------------------------
Ungültige Zeigeroperation.
---------------------------
OK
---------------------------
da dreht Delphi aber auch ganz schön an den Fehlermeldungen (ist beides die "selbe" Exception)

[add]
da war wohl wirklich ein Fehler in TMatheParser.Berechne > Tausche
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 6 von 10   « Erste     456 78     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 00:38 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