![]() |
Re: Langzahlen
Liste der Anhänge anzeigen (Anzahl: 1)
hier mal eine langzahl unit für + - * schnelle potenzen vergleiche und wurzeln
wer noch einen verschlag für die division hat, dem wäre ich sehr dankbar |
Re: Langzahlen
Zitat:
schnelle potenzen: Odd/even-Entscheidung über modul(...,'2'), modul als Differenz mit Quotient*divisor, quotient über wiederholte Differenzen! Quotient liefert extended und keine Pseudolangzahl, etc ... Und dann noch der übliche schlechte Programmierstil: Dialoge in solchen Units, Operationen als Methoden einer Form etc. |
Re: Langzahlen
ich habe es hier hineingestellt, um anregungen für verbesserungen zu bekommen
das ganze soll nicht sonderlich kompliziert werden, nur funktionieren soll es. die eingestellte version ist nur vorab, nachbesserungen am design werden getätigt, sobald alles so funktioniert wie es soll. im moment fehlen mir noch ein effizienter quotient (hat mein vorredner schon angemerkt, dass das sehr schlecht ist bisher) und eine sqrt funktion... |
Re: Langzahlen
Wenn er das mit der
![]() da es so dann zumindestens mal eine für Anfänger leichter verständliche Version sein würde. (wer es schnell mag, der kann ja DEC und Co. verwenden) Aber erstmal wäre es hier gut, wenn alles konsequent auf Strings (bzw. auf ein einheitliches Zahlenformat) umgestellt - die Extended-Parameter zwischendurch machen sich nicht so gut. und in eine eigene Klasse in einer eigenen Unit ausgelagert würde, zusammen mit einer "schönen" Codeformatierung. |
Re: Langzahlen
ich habe bereits versucht, alles auf strings zu ändern, dann funktioniert das ganze jedoch nicht mehr
dies ist auch der grund wieso ich hier nach vorschlägen suche. zur "normalen" schriftlichen division: hatte ich schon probiert, ist jedoch fehlgeschlagen, daher auch der umweg über das wenig elegante string / extended - gemisch. |
Re: Langzahlen
Das einfachste ist erstmal alles das, was geht und schon einem einheitlichem Stil entspricht auszulagen und als eigene Klasse zusammennzufassen.
Dann die Grundfuntionen zum Laufen zu bekommen und sich danach um Optimierungen und Erweiterunen zu kümmern.
Delphi-Quellcode:
function tform1.isOdd(const a: AnsiString): AnsiString; // modul(b, '2') <> '0'
begin Result := (a <> '') and (a[Length(a)] in ['1', '3', '5', '7', '9']); end; function tform1.isEven(const a: AnsiString): AnsiString; // modul(b, '2') = '0' begin Result := (a = '') or (a[Length(a)] in ['0', '2', '4', '6', '8']); end;
Delphi-Quellcode:
da wo intern der String nicht verändert wird, macht sich const besser
type TMathe = class
function summe ( a, b: AnsiString): AnsiString; function differenz( a, b: AnsiString): AnsiString; procedure inc (var a: AnsiString); procedure dec (var a: AnsiString); function produkt ( a, b: AnsiString): AnsiString; function quotient (const a, b: AnsiString): AnsiString; function modul ( a, b: AnsiString): AnsiString; function vergleich( a, b: AnsiString): TValueRelationship; function ungerade (const a: AnsiString): Boolean; function gerade (const a: AnsiString): Boolean; end; (hab es jetzt nicht bei allem gesetzt, da ich nicht weiß, ob es möglich ist) siehe ![]()
Delphi-Quellcode:
var mathe: TMathe;
a, b, c: AnsiString; mathe := TMathe.Create; a := '123'; b := '456'; c := mathe.summe(a, b); if mathe.vergleich(c, '56088') = 0 then ...; mathe.Free; Ja, das mit der Division ist wirklich nicht leicht, wenn ich bedenke, wie ich mich bei meiner Lib da abgequält hab :wall: Im Prinzip kannst kannst du dich auch von hinten rum annähern und dich von der anderen Seite aus, über Additionen oder Multiplikationen schrittweise annähern. der Einachste und leider auch lagsamste Weg wäre
Delphi-Quellcode:
also das sollte erstmal funktionieren
function TMathe.quotient(a, b: AnsiString): AnsiString;
begin result := '0'; while vergleich(a, b) >= 0 do begin result := summe(result, '1'); a := differenz(a, b); end; end; function TMathe.modul(const a, b: AnsiString): AnsiString; begin result := a; while vergleich(result, b) >= 0 do result := differenz(result, b); end; und über eine Multiplication sollte sich da noch was optimieren lassen. |
Re: Langzahlen
Also verständlicher wird es auch mit komplett auf Strings umgestellten Code nicht. Es bleiben immer noch für solche Aufgaben katastrophale Mängel. Weitere Beispiele:
Verwendung von globalen Variablen für Zwischenergebnisse, application.ProcessMessages bei der Divission (wahrscheinlich weil sie sonst zu schnell wäre:), sonstige Bugs '00' > '1' weil length('00') > length('1') etc. Meine Empfehlung an den OP: Versuch's erstmal mit der korrigierten Unit LZahl80, wenn die dann irgendwann nicht mehr ausreicht, zB Knuth's Seminumerical Algorithms (DAS ist verständlich) lesen und die Algorithmen programmieren. |
Re: qwertz543221 kleine String-Math-Lib
Ich habe diesen Thraed vom Thread
![]() |
Re: qwertz543221 kleine String-Math-Lib
zur divisions-idee von himitsu:
den einfachen weg hatte ich schon versucht, leider waren die ergebnisse falsch oder er befand sich in einer endlosschleife. geht das nicht auch anders? |
Re: qwertz543221 kleine String-Math-Lib
Also nach der einfachen Methode sollte das Ergebnis aber zumindestens richtig sein und dem Ergebnis des DIV-Operators entsprechen.
Und Endlosschleife dürfte auch nicht ganz stimmen ... nur halt langsam, da womöglich viele Schleifendurchläufe nötig sind z.B. 1000000 div 2 bzw. mathe.differenz('1000000', '2') benötigt so immerhin schon 500000 Durchläufe Aber es ist einfacher wirklich erstmal aufzuräumen. Es wird später sonst immer schwieriger, da es ja immer mehr und unübersichtlicher wird. Der Vorteil der Klasse bzw. daran daß es in einer eigenen Unit liegt: man kann es später auch mal in anderen Projekten wiederverwenden ... ist es direkt eingebaut, ist es nur da nutzbar, wo es eingebaut wurde. Und ist dir schonmal aufgefallen, daß deine Funktionen nur positive ganze Zahlen mögen? Wie schon von wem erwähnt: Die beiden globalen Strings xa und xb haben da auch nix zu suchen, sie werden nur in der Funktion vergleich verwendet. Ein sehr wichtiger Grund gegen soetwas sind z.B. mehrere Threads ... also wenn z.B. diese Funktion zweimal gleichzeitig in unterschiedlichen Threads verwendet wird, dann wollen beide Funktionen diese Variablen verwenden und "ärgern" sich gegenseitig. :twisted: hier mal ein Vorschlag, für eine Basisklasse:
Delphi-Quellcode:
und zur Verwendung: eine Instanz der Klasse anlegen und schon kann's losgehn
unit StringMathLib;
interface uses Types, SysUtils; type TMathe = class procedure normalisieren(var a: AnsiString); procedure formatieren (var a: AnsiString; tausenderPunkte, immerVorzeichen: Boolean; mindestlaenge: Integer = 0); function summe (const a, b: AnsiString): AnsiString; function differenz (const a, b: AnsiString): AnsiString; procedure plus1 (var a: AnsiString); procedure minus1 (var a: AnsiString); procedure negieren (var a: AnsiString); function produkt (const a, b: AnsiString): AnsiString; function quotient (const a, b: AnsiString): AnsiString; function modul (const a, b: AnsiString): AnsiString; procedure quotientModul(const a, b: AnsiString; var q, m: AnsiString); function vergleich (const a, b: AnsiString): TValueRelationship; function istPositiv (const a: AnsiString): Boolean; function istNegativ (const a: AnsiString): Boolean; function istGerade (const a: AnsiString): Boolean; function istUngerade (const a: AnsiString): Boolean; end; implementation procedure TMathe.normalisieren(var a: AnsiString); var i: Integer; v: Boolean; begin a := Trim(a); for i := Length(a) downto 1 do if not (a[i] in ['0'..'9', ',', '-']) then Delete(a, i, 1); v := False; while (a <> '') and (a[1] = '-') do begin v := not v; Delete(a, 1, 1); end; for i := Length(a) downto 1 do if a[i] = '-' then Delete(a, i, 1); while (a <> '') and (a[1] = '0') do Delete(a, 1, 1); if a = '' then a := '0'; if v then a := '-' + a; end; procedure TMathe.formatieren(var a: AnsiString; tausenderPunkte, immerVorzeichen: Boolean; mindestlaenge: Integer = 0); var i, i2: Integer; begin normalisieren(a); if (a <> '') and (a[1] = '-') then i2 := 2 else i2 := 1; i := Length(a) - 2; while i > i2 do begin Insert('.', a, i); Dec(i, 3); end; if i2 = 1 then begin Insert('+', a, 1); i2 := 2; end; while Length(a) < mindestlaenge do Insert('0', a, i2) end; procedure TMathe.angleichen(var a, b: AnsiString); begin end; function TMathe.summe(const a, b: AnsiString): AnsiString; begin end; function TMathe.differenz(const a, b: AnsiString): AnsiString; begin end; procedure TMathe.plus1(var a: AnsiString); begin end; procedure TMathe.minus1(var a: AnsiString); begin end; procedure TMathe.negieren(var a: AnsiString); begin normalisieren(a); if a[1] = '-' then Delete(a, 1, 1) else Insert('-', a, 1); end; function TMathe.produkt(const a, b: AnsiString): AnsiString; begin end; function TMathe.quotient(const a, b: AnsiString): AnsiString; var m: AnsiString; begin quotientModul(a, b, Result, m); end; function TMathe.modul(const a, b: AnsiString): AnsiString; var q: AnsiString; begin quotientModul(a, b, q, Result); end; procedure TMathe.quotientModul(const a, b: AnsiString; var q, m: AnsiString); begin end; function TMathe.vergleich(const a, b: AnsiString): TValueRelationship; begin end; function TMathe.istPositiv(const a: AnsiString): Boolean; begin normalisieren(a); Result := a[1] <> '-'; end; function TMathe.istNegativ(const a: AnsiString): Boolean; begin normalisieren(a); Result := a[1] = '-'; end; function TMathe.istGerade(const a: AnsiString): Boolean; begin normalisieren(a); Result := a[Length(a)] in ['0', '2', '4', '6', '8']; end; function TMathe.istUngerade(const a: AnsiString): Boolean; begin normalisieren(a); Result := a[Length(a)] in ['1', '3', '5', '7', '9']; end; end.
Delphi-Quellcode:
uses StringMathLib;
var mathe: TMathe; a, b, c: AnsiString; begin mathe := TMathe.Create; a := '123'; b := '456'; c := mathe.summe(a, b); if mathe.vergleich(c, '56088') = 0 then ; mathe.Free; end; |
Re: qwertz543221 kleine String-Math-Lib
kleines Beispiel:
Delphi-Quellcode:
Hab mal das ganze ORD, CHR und sonstiges Umgerechne einfach durch diese Konstanten ersetzt.
function TMathe.summe(a, b: AnsiString): AnsiString;
var i, i2, ueberlauf, x: Integer; begin normalisieren(a); normalisieren(b); if (a[1] = '-') <> (b[1] = '-') then begin negieren(b); Result := differenz(a, b); Exit; end; i2 := Max(Length(a), Length(b)) + 2; // +2 für Überlauf und Vorzeichen formatieren(a, False, True, i2); formatieren(b, False, True, i2); formatieren(Result, False, True, i2); ueberlauf := 0; for i := i2 downto 2 do begin x := (Ord(a[i]) - Ord('0')) + (Ord(b[i]) - Ord('0')) + ueberlauf; Result[i] := Chr(x mod 10 + Ord('0')); ueberlauf := x div 10; end; Result[1] := a[1]; // Vorzeichen normalisieren(Result); end;
Delphi-Quellcode:
Und nun sieht man, daß man mit einer etwas durchdachten und aufgeräumten Klassenstruktur sehr schön übersichtliche Codes entstehen lassen kann
const
ZeichenZuZahl: Array['0'..'9'] of Byte = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); ZahlZuZeichen: Array[0..9] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
Delphi-Quellcode:
function TMathe.summe(a, b: AnsiString): AnsiString;
var i, i2, ueberlauf, x: Integer; begin normalisieren(a); normalisieren(b); if istNegativ(a[1]) <> istNegativ(b[1]) then begin negieren(b); Result := differenz(a, b); Exit; end; i2 := Max(Length(a), Length(b)) + 2; // +2 für Überlauf und Vorzeichen formatieren(a, False, True, i2); formatieren(b, False, True, i2); formatieren(Result, False, True, i2); ueberlauf := 0; for i := i2 downto 2 do begin x := ZeichenZuZahl[a[i]] + ZeichenZuZahl[b[i]] + ueberlauf; Result[i] := ZahlZuZeichen[x mod 10]; ueberlauf := x div 10; end; Result[1] := a[1]; // Vorzeichen normalisieren(Result); end; |
Re: qwertz543221 kleine String-Math-Lib
vielen dank für die anmerkungen - ich werde es, sobald ich dazu komme, umsetzen.
=>bisher hat für mich nur gezählt, dass es die richtigen ergebnisse erzeugt.(Optimierungen sollten später kommen, sobald alles läuft) Da ich das ganze für RSA brauche, habe ich die Negation vernachlässigt. Wie könnte ich denn die division darstellen, vlt schriftlich??, ohne durchprobieren zu müssen? |
Re: qwertz543221 kleine String-Math-Lib
Zitat:
z.B. 456789 div 123 Zitat:
Aber für "aufwändigere" cryptografische Dinge ist soeine Lib dann nicht unbedingt gut geeignet, da sie halt "recht" langsam arbeitet. Wenn du dir mal die andere Lib vom Dipl. Ernst Winter ansiehst, dann arbeitet diese bei jedem internem Rechenschritt 6 Dezimalstellen gleichzeitig ab und hier ist es jeweils nur Eine. Bei meiner Lib sind es noch ein paar mehr, da ich direkt binär rechne und jedes Bit ausnutze (siehe ![]() Wenn du wirklich stark in Richtung Cryptography arbeiten willst, dann empfehle ich dir das DEC, denn diese Lib ist speziell für soetwas entwickelt wurden. Was soeine String-Lib aber aus macht: - sie ist sehr gut zu debuggen und vorallem von "Laien" dürfte verstanden werden, was da intern abläuft - nja und die Zahlenlänge ist nahezu unbegrenzt ... eine "normale" Win32-Anwendung bekommt man locker eine Zahl mit einer Milliade Stellen :angel: (ok, die verbraucht dann zwar auch fast 1 GB an Arbeitsspeicher, aber es paßt rein) |
Re: qwertz543221 kleine String-Math-Lib
Danke für deine erläuterungen. ich werde das gleich mal testen.
die einfachheit ist gut, denn zu hochtrabend sollte das ganze ja nicht sein. das DEC schaue ich mir trotzdem einmal an, vlt finde ich dort etwas, das ich gebrauchen kann ( - und verstehe, was notwendig ist, um es auch ordnungsgemäß einzubinden;)) |
Re: qwertz543221 kleine String-Math-Lib
noch eine frage:
was meintest du hiermit "parallel dazu das den Quotient um 10^verschobeneStellen erhöhen (dazuaddieren) " |
Re: qwertz543221 kleine String-Math-Lib
meintest du das so??:
Delphi-Quellcode:
[edit=mkinzler]Delphi-Tag eingefügt; Code eingerückt Mfg, mkinzler[/edit]
function tform1.quotient(a,b:ansistring):ansistring;
var stellen:longint; begin result := '0'; stellen:=0; while length(b)<length(a) do begin b:=b+'0'; stellen:=stellen+1; end; while (vergleich(a,b)=0)and(stellen>0)do //divident >divisor begin result:=summe(result,floattostr(trunc(power(10,stellen)))); a:=differenz(a,b); end; delete(a,length(a)-1,length(a)); stellen:=stellen-1; end; |
Re: qwertz543221 kleine String-Math-Lib
die innere Schleife etwas anders geordnet:
Zitat:
Delphi-Quellcode:
Quotient := summe(Quotient, potenz(10, verschobeneStellen));
|
Re: qwertz543221 kleine String-Math-Lib
ich hab das einmal als qt erstellt, aber ich denke, ich habe deine anweisungen misverstanden. (ergo: es funktioniert nicht;))
Delphi-Quellcode:
[edit=mkinzler]Delphi-Tag eingefügt. Das nächste Mal bitte selber machen! Mfg, mkinzler[/edit]
function tform1.quotient(a,b:ansistring):ansistring;
var stellen:longint; begin result := '0'; stellen:=0; while length(b)<length(a) do begin b:=b+'0'; stellen:=stellen+1; end; while stellen>0 do begin while vergleich(b,a)=0 do //b>a? result:=result+floattostr(trunc(power(10,stellen))); delete(a,length(a)-1,1); stellen:=stellen-1; end; end; |
Re: qwertz543221 kleine String-Math-Lib
Zitat:
Delphi-Quellcode:
Aber durch deine wiederholte Vermischung mit Extended begrenzt du die maximale Rechengröße auf 19 Stellen.
// c = Stellen
function tform1.Quotient(a, b: AnsiString): AnsiString; var c: Int64; begin if b = '0' then System.Error(reDivByZero); Result := '0'; c := 0; while Length(b) < Length(a) do begin c := c + 1; b := b + '0'; // b := produkt(b, '10'); end; while c >= 0 do begin while vergleich(b, a) <= 0 do begin Result := summe(Result, inttostr(trunc(power(10, c)))); a := differenz(a, b); end; c := c div 10; // a := quotient(a, '10'); Delete(b, Length(b), 1); // b := quotient(b, '10'); end; end; In diesem Fall ist es zum Glück nur die Differenz zwischen Stellen von a und b, aber über die ganze Lib gesehen, wird somit der die maximale Zahlengröße in (abgesehn von der Addition und Subtraktion) auf 19 Dezimalstellen begrenzt und man könnte genausogut mit direkt Int64 arbeiten. Extended hat zwar einen sehr großen Wertebereich, aber nur 19-20 signifikante Stellen. heißt: es sind nur die erst 19 bis 20 Stellen gepspeichert und alle nachfolgenden Stellen snd Aufgrund der internen Struktur undefiniert und von Rundungsfehlern überschattet. Darum mußt du aufpassen, daß du wärend der Berechnungen bei deinem Zahlentyp bleibst und keine der "kleinen" Standardtypen verwendest:
Delphi-Quellcode:
// c = 10^Stellen
function tform1.Quotient(a, b: AnsiString): AnsiString; var c: AnsiString; begin if b = '0' then System.Error(reDivByZero); Result := '0'; c := '1'; while Length(b) < Length(a) do begin c := c + '0'; // c := produkt(c, '10'); b := b + '0'; // b := produkt(b, '10'); end; while c <> '' do begin while vergleich(b, a) <= 0 do begin Result := summe(Result, c); a := differenz(a, b); end; Delete(c, Length(c), 1); // a := quotient(a, '10'); Delete(b, Length(b), 1); // b := quotient(b, '10'); end; end; |
Re: qwertz543221 kleine String-Math-Lib
ich habe deinen vorschlag ausprobiert. anscheinend sind meine anderen funktionen nicht dafür geeignet. - das ergebnis stimmt fast nie.
ich gebe mal die weiteren fkts mit, vlt versteckt sich dort ein fehler ( ich konnte keinen finden, da die fkts an sich ihren dienst ordnungsgemäß erfüllen) -----------------------------------------------------------------------------------------------------
Delphi-Quellcode:
[edit=mkinzler]Delphi-Tag eingefügt Mfg, mkinzler[/edit]
function summe(a,b:ansistring):ansistring;
var i,l:longint; u:longint; begin //mit Nullen auffüllen: l:=length(a); while l<length(b) do begin a:='0'+a; l:=l+1; end; l:=length(b); if length(a)>length(b) then while length(a)>length(b) do begin b:='0'+b; l:=l+1; end else if length(b)>length(a) then while length(b)>length(a) do begin a:='0'+a; l:=l+1; end; u:=0; //Maximallänge festlegen if length(a)>=length(b) then i:=length(a) else i:=length(b); while i>=1 do begin //addition a+b+u result:=inttostr((strtoint(a[i])+strtoint(b[i])+u)mod 10)+result; //berechnung u u:=(u+strtoint(a[i])+strtoint(b[i]) )div 10; i:=i-1; end; i:=1; result:=inttostr(u)+result; a:=result; //führende '0' löschen while a[1]='0' do delete(a,1,1); result:=a; end; function differenz(a,b:ansistring):ansistring; var u,i,j,la,lb:longint; c:ansistring; begin //zwei gleiche Zahlen: if a=b then result:='0' else //a>b? if (vergleich(a,b)<>0 )and(a<>b) then begin showmessage('Subtraktion nicht möglich.'); exit; end else begin //initialisieren result:=''; la:=length(a); lb:=length(b); //anfangsübertrag setzen u:=0; j:=1; //mit nullen füllen if la<lb then while la<lb do begin a:='0'+a; la:=la+1; end else if lb<la then while length(a)>length(b) do begin b:='0'+b; lb:=lb+1; end; //subtraktion beginnen - vgl. schriftliches rechnen i:=length(b); //von vorne nach hinten while i>=1 do begin //übertrag? if u=0 then begin //neuen übertrag setzen if strtoint(a[i])<strtoint(b[i]) then u:=10 else u:=0; // nächste stelle des ergebnisses berechnen result:=inttostr((strtoint(a[i])+u-strtoint(b[i]))mod 10)+result; end else begin //wenn übertrag vorhanden: if strtoint(a[i])<strtoint(b[i])+1 then u:=10 else u:=0; //bei der nächten stelle eines subtrahieren,da übertrag; einerstelle zum ergebnis //hinzufügen result:=inttostr((strtoint(a[i])+u-1-strtoint(b[i])mod 10))+result end; i:=i-1; end; //führende nullen löschen c:=result; while c[1]='0' do delete(c,1,1); result:=c end; end; |
Re: qwertz543221 kleine String-Math-Lib
@qwertz543221: Die Aufforderung Delphi-Tags zu verwenden und den Code richtig einzurücken war ernst gemeint. Bitte mache dies in der Zukunft! :warn:
|
Re: qwertz543221 kleine String-Math-Lib
Die das letzte Quotient-Funktion entspricht etwa meiner ... nur etwas gekürzt
summe scheint schonmal richtig zu laufen Und kann es sein, daß zugfällig diese Meldung angezeigt wird? Denn dieses sollte immer "wahr" / True melden und auslösen, da hier A immer <> B ist.
Delphi-Quellcode:
//a>b? <> (vergleich(a,b)<>0 )and(a<>b)
//zwei gleiche Zahlen:
if a=b then result:='0' else //a>b? if (vergleich(a,b)<>0 )and(a<>b) then begin showmessage('Subtraktion nicht möglich.'); exit; end Ich vermute mal du wolltes da ein > und nicht <> verwenden. obwohl es bei dir eigentlich < sein müßte ... a<b, da dann ein negatives Ergebnis rauskommen täte. Und warum einmal Stringvergleich und zusätzlich per Funktion? Mein Tipp: einen Breakpoint setzen und dann intensive Nutzung der Taste F7 :angel: |
Re: qwertz543221 kleine String-Math-Lib
Zitat:
Zitat:
also alles danach wird niemal abgearbeitet
Delphi-Quellcode:
if vergleich(a,b)<0
then Zitat:
dann mit F7 in Ruhe die Funktion abarbeiten und dabei schauen was mit den ganzen Variablen passiert dafür gibt es unter Strg+Alt+W ein Fenster, wo man Variablennamen eintragen kann oder man höllt die Maus mal ein paar Sekündchen über eine Variable im Code und bekommt so ihren Inhalt angezeigt. Zitat:
gut, da es sich hier ja, aus Sicht des PCs um "alleinstehende" einzelne Dezimalzahlen handelt, müssen wir diese halt auch komplett behandeln und dann jeweils um eine ganze verschieben. Bei einer "rein" binären Lib, hätte man hier Bitweise gehen können und dann schön über shl die ganzen Bits verschieben können. Problem ist halt, daß soeine auf Strings aufbauende Lib nunmal nicht ganz mit dem Wort Effizienz vereinbar ist. |
Re: qwertz543221 kleine String-Math-Lib
Liste der Anhänge anzeigen (Anzahl: 1)
hallo, ich habe das projekt einmal als rar hochgeladen, dann kannst du es testen
vlt liegt es nur an einer kleinigkeit - das ist ja meistens so beim programmieren - oder ich habe deine vorschläge einfach falsch interpretiert. mfG |
Re: qwertz543221 kleine String-Math-Lib
OK, das kommt davon, wenn man bei seiner Vergleichsfunktion fernab von jeglichen Standards seine Rückgabewerte definiert ... hatte ganz übersehen, daß diese anders vergleicht.
mach mal aus dem
Delphi-Quellcode:
dieses hier
while vergleich(b, a) <= 0 do
Delphi-Quellcode:
ich hoff das stimmt dann
while vergleich(b, a) >= 1 do
standard: 0 a=b -1 a<b 1 a>b und zum Auswerten dann
Delphi-Quellcode:
du siehst ... so verhält sich dann a zu b wie "vergleich" zu 0
if vergleich(a, b) < 0 then a < b if vergleich(a, b) = -1 then
if vergleich(a, b) <= 0 then a <= b if vergleich(a, b) = 0 then a = b if vergleich(a, b) >= 0 then a >= b if vergleich(a, b) > 0 then a > b if vergleich(a, b) = 1 then if vergleich(a, b) <> 0 then a <> b oder man nutzt bei seiner Vergleichs-Funktion das TValueRelationship aus der Unit Types (wie vorher schonmal vorgeschlagen), dann fällt zusätzlich noch auf, daß auch sowas geht
Delphi-Quellcode:
if vergleich(a, b) = LessThanValue then a < b
if vergleich(a, b) <> GreaterThanValue then a <= b if vergleich(a, b) = EqualsValue then a = b if vergleich(a, b) <> LessThanValue then a >= b if vergleich(a, b) = GreaterThanValue then a > b if vergleich(a, b) <> EqualsValue then a <> b |
Re: qwertz543221 kleine String-Math-Lib
also das sollte jetzt bei dir Laufen ...
Delphi-Quellcode:
es gibt nur ein Problem ...
function tform1.Quotient(a, b: AnsiString): AnsiString;
var c: Int64; begin if b = '0' then System.Error(reDivByZero); Result := '0'; c := 0; while Length(b) < Length(a) do begin c := c + 1; b := b + '0'; // b := produkt(b, '10'); end; while c >= 0 do begin while vergleich(b, a) <> 0 do begin Result := summe(Result, inttostr(trunc(power(10, c)))); a := differenz(a, b); end; c := c - 1; Delete(b, Length(b), 1); // b := quotient(b, '10'); end; end; die Funktion summe rechnet falsch ... und zwar wenn man sie einzeln benutzt, dann 1+1=2 aber in der schleife 0+1=1 ... 1+1=21 ... 21+1=221 ..... da ich aber bei deiner Summenfunktion einfach nicht durchseh, mußt'e den Fehler da wohl selber finden (hat vielleicht was mit den gloablen Variablen zu tun? :gruebel: ) [add] Problem gefunden ... du hast in Summe das result nicht initialisiert:!: ein result:=''; vor der Berechnung liefert Abhilfe. und noch einen Tipp: das result wurde auch in anderen Funktionen nicht initialisert :zwinker: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:17 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