Einzelnen Beitrag anzeigen

Benutzerbild von GPRSNerd
GPRSNerd

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

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

  Alt 8. Jul 2009, 14: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