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 9 von 10   « Erste     789 10      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.336 Beiträge
 
Delphi 12 Athens
 
#1

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 3. Jul 2009, 17:03
ganz vorne im Ersten, also Post #1

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

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.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#2

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 3. Jul 2009, 17:21
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:
  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;
Statt "istNegativ" müsste abgefragt werden, ob das erste Zeichen ein Vorzeichen ist.
Also stattdessen:
If Ord(a[Length(a)]) in [Ord('+'), Ord('-')] Then Dec(Result); MfG
xZise
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.336 Beiträge
 
Delphi 12 Athens
 
#3

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 3. Jul 2009, 17:45
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

Delphi-Quellcode:
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);
PS: unnormalisiert wäre z.B. '-++-+---+-2' eine gültige Zahl
und was möge wohl passieren, wenn als Eingabestring mal ein '' durchkäme


ansonsten steht schon seit langem sowas im ersten Post und beim nächsten Update auch in der kleinen Inlinehile in der StringMatheLib.pas
Zitat von himitsu:
» 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. Nerd
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.336 Beiträge
 
Delphi 12 Athens
 
#4

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 3. Jul 2009, 21:15
ChangeLog
[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)


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 )

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
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 8. Jul 2009, 13:41
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
function ZahlNToINT(const ZahlN, BasisN: string): string; 2. Aus dem Dezimal-System in beliebige Zahlensysteme zur Basis N
function INTToZahlN(const Zahl10, BasisN: string): string; 3. und die Verallgemeinerung von Basis N in Basis M
function ZahlNToZahlM(const ZahlN, BasisN, BasisM: string): string; Ein paar benötigte Hilfefunktionen sind auch noch dabei:
1. Bereinigen des Zahlstrings von nicht erlaubten Zeichen
function ZahlNBereinigen(const ZahlN, BasisN: string): string; 2. (private) Funktionen zum Zuweisen Werten zu Ziffern und umgekehrt
Delphi-Quellcode:
function _GetZahl(const Value: Char): Integer;
function _GetZeichen(const Number: Integer): String;
Augerufen werden die public functions so:
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:
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;
Gruß,
Stefan
Stefan
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#6

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 8. Jul 2009, 14:19
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.
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#7

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 8. Jul 2009, 14:29
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;
Stefan
  Mit Zitat antworten Zitat
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#8

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 8. Jul 2009, 14:43
Zitat von gammatester:
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.
Kann man ja dann ganz einfach folgendermaßen berücksichtigen, wobei man sich allerdings bewusst sein sollte, dass es dann ganz schön "knallen" kann, wenn das vorrausgesetzte Zahlenformat nicht eingehalten wird:

Delphi-Quellcode:
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;
Über die Fehlerbehandlung (Exception-Raising) müsste man dann nochmal nachdenken...
Stefan
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#9

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 8. Jul 2009, 15:03
Zitat von GPRSNerd:
Kann man ja dann ganz einfach folgendermaßen berücksichtigen, wobei man sich allerdings bewusst sein sollte, dass es dann ganz schön "knallen" kann, wenn das vorrausgesetzte Zahlenformat nicht eingehalten wird:
Ein kontrollierter Knall ist immer noch besser als völlig unkontrollierbare falsche Ergebnisse, und außerdem wohl in jeder ernstzunehmenden Programmiersprache/Interpreter die Regel.

Gruß Gammatester
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.336 Beiträge
 
Delphi 12 Athens
 
#10

Re: Mathe mit Strings (die deutsche StringMatheLib ._. )

  Alt 18. Jul 2009, 07:04
Delphi-Quellcode:
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;
der Defaultstring reicht bis Basis 64

Delphi-Quellcode:
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'
falls Keiner was einzuwenden hat, bau ich's bei Gelegenheit mit ein
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 9 von 10   « Erste     789 10      


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:10 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-2025 by Thomas Breitkreuz