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