es wurde ja schon oft das Thema angesprochen, wie man mit sehr großen Ganzzahlen rechnen kann.
Ich habe ein Unit entwickelt, mit welchem das möglich ist.
Alle Zahlen und Ergebnisse werden in Strings abgespeichert.
Mit diesen Algorithmen ist es nun ein einfaches erweiterte Algorithmen wie z.B. für große Fakultäten, kgV, ggT zu entwickeln.
Auch Primzahlen ließen sich berechnen. Dies ist aber nur theoretisch möglich, weil sehr große Primzahlen jegliche Rechenzeit springen.
Hir nun die Unit:
Code: Alles auswählen
Unit StringMathe;
Interface
Function AdditionInteger(Zahl1,Zahl2:String):String;
Function SubtraktionInteger(Zahl1,Zahl2:String):String;
Function MultiplikationInteger(Zahl1,Zahl2:String):String;
Function DivisionInteger(Zahl1,Zahl2:String):String;
Function ModuloInteger(Zahl1,Zahl2:String):String;
Implementation
Const MaxLaenge =500;
ErgebnisFehler=1E2000;
Var MaxInt64:Int64;
Function ValueInteger(s:String):Extended;
Var Fehler:Integer;
Zahl :Extended;
Begin
Val(s,Zahl,Fehler);
If Fehler<>0 Then ValueInteger:=ErgebnisFehler
Else ValueInteger:=Int(Zahl)
End;
Function VorzeichenErgaenzenInteger(s:String):String;
Begin
If s[1]='+' Then s[1]:=' ';
If (s[1]>='0') And (s[1]<='9') Then s:=' '+s;
VorzeichenErgaenzenInteger:=s
End;
Function AbsolutInteger(s:String):String;
Begin
If (s[1]='+') Or (s[1]='-') Then s[1]:=' ';
AbsolutInteger:=s
End;
Function StringVerkuerzenInteger(s:String):String;
Var i:Integer;
h:String;
c:Char;
Begin
c:=s[1];i:=2;
While s[i]='0' Do Inc(i);
h:=c+Copy(s,i,Length(s)-i+1);
If (h=' ') Or (h='+') Or (h='-') Then h:=' 0';
If h='-0' Then h:=' 0';
StringVerkuerzenInteger:=h
End;
Function StringVerlaengernInteger(s,Null:String):String;
Begin
StringVerlaengernInteger:=s[1]+Copy(Null,1,Length(Null)-Length(s)+1)+
Copy(s,2,Length(s))
End;
Function Replicate(s:Char;WieOft:Integer):String;
Var i:Integer;
t:String;
Begin
t:='';
For i:=1 To WieOft Do t:=t+s;
Replicate:=t
End;
Function GroesserInteger(s1,s2:String):Boolean;
Begin
s1:=StringVerkuerzenInteger(s1);s2:=StringVerkuerzenInteger(s2);
If s1=s2 Then Begin GroesserInteger:=False;Exit End;
If (s1[1]=' ') And (s2[1]='-') Then Begin GroesserInteger:=True;Exit End;
If (s1[1]='-') And (s2[1]=' ') Then Begin GroesserInteger:=False;Exit End;
If (s1[1]=' ') And (s2[1]=' ') Then
Begin
If Length(s1)>Length(s2) Then Begin GroesserInteger:=True;Exit End;
If Length(s1)<Length(s2) Then Begin GroesserInteger:=False;Exit End;
If s1>s2 Then Begin GroesserInteger:=True;Exit End;
GroesserInteger:=False;Exit
End;
If (s1[1]='-') And (s2[1]='-') Then
Begin
If Length(s1)>Length(s2) Then Begin GroesserInteger:=False;Exit End;
If Length(s1)<Length(s2) Then Begin GroesserInteger:=True;Exit End;
If s1>s2 Then Begin GroesserInteger:=False;Exit End;
GroesserInteger:=True;Exit
End;
GroesserInteger:=False
End;
Function KleinerInteger(s1,s2:String):Boolean;
Begin
s1:=StringVerkuerzenInteger(s1);s2:=StringVerkuerzenInteger(s2);
If s1=s2 Then Begin KleinerInteger:=False;Exit End;
If (s1[1]='-') And (s2[1]=' ') Then Begin KleinerInteger:=True;Exit End;
If (s1[1]=' ') And (s2[1]='-') Then Begin KleinerInteger:=False;Exit End;
If (s1[1]=' ') And (s2[1]=' ') Then
Begin
If Length(s1)<Length(s2) Then Begin KleinerInteger:=True;Exit End;
If Length(s1)>Length(s2) Then Begin KleinerInteger:=False;Exit End;
If s1<s2 Then Begin KleinerInteger:=True;Exit End;
KleinerInteger:=False;Exit
End;
If (s1[1]='-') And (s2[1]='-') Then
Begin
If Length(s1)<Length(s2) Then Begin KleinerInteger:=False;Exit End;
If Length(s1)>Length(s2) Then Begin KleinerInteger:=True;Exit End;
If s1<s2 Then Begin KleinerInteger:=False;Exit End;
KleinerInteger:=True;Exit
End;
KleinerInteger:=False
End;
Function GleichInteger(s1,s2:String):Boolean;
Begin
s1:=StringVerkuerzenInteger(s1);s2:=StringVerkuerzenInteger(s2);
If s1=s2 Then GleichInteger:=True Else GleichInteger:=False
End;
Function AdditionInteger(Zahl1,Zahl2:String):String;
Var Ergebnis,Null:String;
i,z,CF :Integer;
Vz1,Vz2,Vz :Boolean;
z1,z2,e :Int64;
Begin
AdditionInteger:='?';
If (Length(Zahl1)<1) Or (Length(Zahl2)<1) Or (Zahl1='?') Or (Zahl2='?') Then Exit;
If Not(ValueInteger(Zahl1)<ErgebnisFehler) Then Exit;
If Not(ValueInteger(Zahl2)<ErgebnisFehler) Then Exit;
Zahl1:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl1));
Zahl2:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl2));
If ValueInteger(Zahl1)=0 Then Begin AdditionInteger:=Zahl2;Exit End;
If ValueInteger(Zahl2)=0 Then Begin AdditionInteger:=Zahl1;Exit End;
If (ValueInteger(AbsolutInteger(Zahl1))<MaxInt64 Div 2) And
(ValueInteger(AbsolutInteger(Zahl2))<MaxInt64 Div 2) Then
Begin
z1:=Trunc(ValueInteger(Zahl1));z2:=Trunc(ValueInteger(Zahl2));e:=z1+z2;
Str(e,Ergebnis);AdditionInteger:=VorzeichenErgaenzenInteger(Ergebnis);Exit
End;
If Zahl1[1]='-' Then Vz1:=True Else Vz1:=False;
If Zahl2[1]='-' Then Vz2:=True Else Vz2:=False;
If Length(Zahl1)>=Length(Zahl2) Then Null:=Replicate('0',Length(Zahl1))
Else Null:=Replicate('0',Length(Zahl2));
CF:=0;Ergebnis:=' '+Null;Vz:=False;
Zahl1:=AbsolutInteger(StringVerlaengernInteger(Zahl1,Null));
Zahl2:=AbsolutInteger(StringVerlaengernInteger(Zahl2,Null));
If (Vz1 And Not(Vz2)) Or (Vz2 And Not(Vz1)) Then
Begin
Ergebnis:=SubtraktionInteger(Zahl1,Zahl2);
If GroesserInteger(Zahl2,Zahl1) Then If Vz2 Then Vz:=True
Else
Else If Vz1 Then Vz:=True
End
Else
Begin
If Vz1 And Vz2 Then Vz:=True;
For i:=Length(Zahl1) DownTo 2 Do
Begin
z:=Ord(Zahl1[i])+Ord(Zahl2[i])-2*Ord('0')+CF;
If z>=10 Then Begin Dec(z,10);CF:=1 End Else CF:=0;
Ergebnis[i]:=Chr(z+Ord('0'))
End
End;
Ergebnis:=StringVerkuerzenInteger(Ergebnis);
If (ValueInteger(Ergebnis)<>0) And Vz Then Ergebnis[1]:='-' Else Ergebnis[1]:=' ';
AdditionInteger:=Ergebnis
End;
Function SubtraktionInteger(Zahl1,Zahl2:String):String;
Var Ergebnis,Null:String;
i,z,BF :Integer;
Vz1,Vz2,Vz :Boolean;
z1,z2,e :Int64;
Begin
SubtraktionInteger:='?';
If (Length(Zahl1)<1) Or (Length(Zahl2)<1) Or (Zahl1='?') Or (Zahl2='?') Then Exit;
If Not(ValueInteger(Zahl1)<ErgebnisFehler) Then Exit;
If Not(ValueInteger(Zahl2)<ErgebnisFehler) Then Exit;
Zahl1:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl1));
Zahl2:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl2));
If Zahl1[1]='-' Then Vz1:=True Else Vz1:=False;
If Zahl2[1]='-' Then Vz2:=True Else Vz2:=False;
If ValueInteger(Zahl1)=0 Then
Begin
If (ValueInteger(Zahl2)=0) Or Vz2 Then Zahl2[1]:=' ' Else Zahl2[1]:='-';
SubtraktionInteger:=Zahl2;Exit
End;
If ValueInteger(Zahl2)=0 Then Begin SubtraktionInteger:=Zahl1;Exit End;
If (ValueInteger(AbsolutInteger(Zahl1))<MaxInt64 Div 2) And
(ValueInteger(AbsolutInteger(Zahl2))<MaxInt64 Div 2) Then
Begin
z1:=Trunc(ValueInteger(Zahl1));z2:=Trunc(ValueInteger(Zahl2));e:=z1-z2;
Str(e,Ergebnis);SubtraktionInteger:=VorzeichenErgaenzenInteger(Ergebnis);Exit
End;
If Length(Zahl1)>=Length(Zahl2) Then Null:=Replicate('0',Length(Zahl1))
Else Null:=Replicate('0',Length(Zahl1));
BF:=0;Ergebnis:=' '+Null;Vz:=False;
Zahl1:=AbsolutInteger(StringVerlaengernInteger(Zahl1,Null));
Zahl2:=AbsolutInteger(StringVerlaengernInteger(Zahl2,Null));
If (Vz1 And Not(Vz2)) Or (Vz2 And Not(Vz1)) Then
Begin
Ergebnis:=AdditionInteger(Zahl1,Zahl2);
If Vz1 Then Vz:=True
End
Else
Begin
If GroesserInteger(Zahl2,Zahl1) Then
Begin
Ergebnis:=Zahl1;Zahl1:=Zahl2;Zahl2:=Ergebnis;Ergebnis:=' '+Null;
If Not(Vz1) And Not(Vz2) Then Vz:=True
End
Else If Vz1 and Vz2 Then Vz:=True;
For i:=Length(Zahl1) DownTo 2 Do
Begin
z:=Ord(Zahl1[i])-Ord(Zahl2[i])-BF;
If z<0 Then Begin Inc(z,10);BF:=1 End Else BF:=0;
Ergebnis[i]:=Chr(z+Ord('0'))
End
End;
Ergebnis:=StringVerkuerzenInteger(Ergebnis);
If (ValueInteger(Ergebnis)<>0) And Vz Then Ergebnis[1]:='-' Else Ergebnis[1]:=' ';
SubtraktionInteger:=Ergebnis
End;
Function MultiplikationInteger(Zahl1,Zahl2:String):String;
Var i,l,z,CF :Integer;
t,Ergebnis,Null:String;
Vz1,Vz2 :Boolean;
z1,z2,e :Int64;
Begin
MultiplikationInteger:='?';
If (Length(Zahl1)<1) Or (Length(Zahl2)<1) Or (Zahl1='?') Or (Zahl2='?') Then Exit;
If Not(ValueInteger(Zahl1)<ErgebnisFehler) Then Exit;
If Not(ValueInteger(Zahl2)<ErgebnisFehler) Then Exit;
Zahl1:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl1));
Zahl2:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl2));
If Length(Zahl1)+Length(Zahl2)>MaxLaenge*2 Then Exit;
If (ValueInteger(Zahl1)=0) Or (ValueInteger(Zahl2)=0) Then
Begin MultiplikationInteger:=' 0';Exit End;
If (ValueInteger(AbsolutInteger(Zahl1))<MaxIntSqrt64) And
(ValueInteger(AbsolutInteger(Zahl2))<MaxIntSqrt64) Then
Begin
z1:=Trunc(ValueInteger(Zahl1));z2:=Trunc(ValueInteger(Zahl2));e:=z1*z2;
Str(e,Ergebnis);MultiplikationInteger:=VorzeichenErgaenzenInteger(Ergebnis);Exit
End;
If Zahl1[1]='-' Then Vz1:=True Else Vz1:=False;
If Zahl2[1]='-' Then Vz2:=True Else Vz2:=False;
Null:=Replicate('0',Length(Zahl1)+Length(Zahl2)-1);CF:=0;Ergebnis:=' '+Null;
If Length(Zahl2)>Length(Zahl1) Then
Begin Ergebnis:=Zahl1;Zahl1:=Zahl2;Zahl2:=Ergebnis;Ergebnis:=' '+Null End;
If ValueInteger(AbsolutInteger(Zahl1))=1 Then Ergebnis:=Zahl2
Else
Begin
If ValueInteger(AbsolutInteger(Zahl2))=1 Then Ergebnis:=Zahl1
Else
Begin
For i:=Length(Zahl2) DownTo 2 Do
Begin
t:=' '+Null;
For l:=Length(Zahl1) DownTo 2 Do
Begin
z:=(Ord(Zahl1[l])-Ord('0'))*(Ord(Zahl2[i])-Ord('0'))+CF;
If z>=10 Then Begin CF:=z Div 10;z:=z Mod 10 End Else CF:=0;
t[i+l]:=Chr(z+Ord('0'))
End;
t[i+1]:=Chr(CF+Ord('0'));CF:=0;Ergebnis:=AdditionInteger(Ergebnis,t)
End
End
End;
Ergebnis:=StringVerkuerzenInteger(Ergebnis);
If (ValueInteger(Ergebnis)<>0) And
((Vz1 And Not(Vz2)) Or (Not(Vz1) And Vz2)) Then Ergebnis[1]:='-' Else Ergebnis[1]:=' ';
MultiplikationInteger:=Ergebnis
End;
Function DivisionInteger(Zahl1,Zahl2:String):String;
Var i :Integer;
t,Ergebnis,Null,z:String;
Vz1,Vz2 :Boolean;
z1,z2,e :Int64;
Begin
DivisionInteger:='?';
If (Length(Zahl1)<1) Or (Length(Zahl2)<1) Or (Zahl1='?') Or (Zahl2='?') Then Exit;
If Not(ValueInteger(Zahl1)<ErgebnisFehler) Then Exit;
If Not(ValueInteger(Zahl2)<ErgebnisFehler) Then Exit;
Zahl1:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl1));
Zahl2:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl2));
If (Length(Zahl1)-Length(Zahl2)>MaxLaenge) Or (ValueInteger(Zahl2)=0) Then Exit;
If GroesserInteger(AbsolutInteger(Zahl2),AbsolutInteger(Zahl1)) Or
(ValueInteger(Zahl1)=0) Then Begin DivisionInteger:=' 0';Exit End;
If Zahl1[1]='-' Then Vz1:=True Else Vz1:=False;
If Zahl2[1]='-' Then Vz2:=True Else Vz2:=False;
Null:=Replicate('0',Length(Zahl1));Ergebnis:=' ';
Zahl1:=AbsolutInteger(StringVerlaengernInteger(Zahl1,Null));
Zahl2:=AbsolutInteger(Zahl2);
If Zahl1=Zahl2 Then Ergebnis:=' 1'
Else
If ValueInteger(Zahl2)=1 Then Ergebnis:=Zahl1
Else
Begin
If (ValueInteger(AbsolutInteger(Zahl1))<MaxInt64) And
(ValueInteger(AbsolutInteger(Zahl2))<MaxInt64) Then
Begin
z1:=Trunc(ValueInteger(Zahl1));z2:=Trunc(ValueInteger(Zahl2));e:=z1 Div z2;
Str(e,Ergebnis);DivisionInteger:=VorzeichenErgaenzenInteger(Ergebnis);Exit
End;
For i:=Length(Zahl2) To Length(Zahl1) Do
Begin
t:=Copy(Zahl1,1,i);z:=' 0';
If GroesserInteger(t,Zahl2) Or GleichInteger(t,Zahl2) Then
Begin
Repeat
t:=SubtraktionInteger(t,Zahl2);z:=AdditionInteger(z,' 1')
Until KleinerInteger(t,Zahl2);
t:=MultiplikationInteger(z,Zahl2);
While KleinerInteger(t+'0',Zahl1) Or GleichInteger(t+'0',Zahl1) Do t:=t+'0';
Zahl1:=StringVerlaengernInteger(SubtraktionInteger(Zahl1,t),Null)
End;
Ergebnis:=Ergebnis+z[2]
End
End;
Ergebnis:=StringVerkuerzenInteger(Ergebnis);
If (ValueInteger(Ergebnis)<>0) And
((Vz1 And Not(Vz2)) Or (Not(Vz1) And Vz2)) Then Ergebnis[1]:='-' Else Ergebnis[1]:=' ';
DivisionInteger:=Ergebnis
End;
Function ModuloInteger(Zahl1,Zahl2:String):String;
Var Ergebnis:String;
z1,z2,e :Int64;
Begin
ModuloInteger:='?';
If (Length(Zahl1)<1) Or (Length(Zahl2)<1) Or (Zahl1='?') Or (Zahl2='?') Then Exit;
If Not(ValueInteger(Zahl1)<ErgebnisFehler) Then Exit;
If Not(ValueInteger(Zahl1)<ErgebnisFehler) Then Exit;
If ValueInteger(Zahl2)=0 Then Exit;
Zahl1:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl1));
Zahl2:=StringVerkuerzenInteger(VorzeichenErgaenzenInteger(Zahl2));
If GleichInteger(AbsolutInteger(Zahl1),AbsolutInteger(Zahl2)) Then
Begin ModuloInteger:=' 0';Exit End;
If GroesserInteger(AbsolutInteger(Zahl2),AbsolutInteger(Zahl1)) Then
Begin ModuloInteger:=Zahl1;Exit End;
If (ValueInteger(AbsolutInteger(Zahl1))<MaxInt64) And
(ValueInteger(AbsolutInteger(Zahl2))<MaxInt64) Then
Begin
z1:=Trunc(ValueInteger(Zahl1));z2:=Trunc(ValueInteger(Zahl2));e:=z1 Mod z2;
Str(e,Ergebnis);ModuloInteger:=VorzeichenErgaenzenInteger(Ergebnis);Exit
End;
Ergebnis:=SubtraktionInteger(Zahl1,MultiplikationInteger(DivisionInteger(Zahl1,Zahl2),Zahl2));
ModuloInteger:=Ergebnis
End;
Begin MaxInt64:=Trunc(9E18) End.
Viel Spaß beim ausprobieren.
Gruß Heizkoerper
P.S. Auf meiner sehr sporadischen Webseite (http://www.wweeke.de) ist das Programm Langzahlen mit dieser Unit entwickelt worden.