![]() |
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; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:42 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