AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

qwertz543221 kleine String-Math-Lib

Ein Thema von qwertz543221 · begonnen am 11. Jun 2009 · letzter Beitrag vom 14. Jun 2009
Antwort Antwort
Seite 1 von 3  1 23      
qwertz543221
(Gast)

n/a Beiträge
 
#1

Re: Langzahlen

  Alt 11. Jun 2009, 19:54
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
Angehängte Dateien
Dateityp: pas unit1_574.pas (9,6 KB, 35x aufgerufen)
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#2

Re: Langzahlen

  Alt 11. Jun 2009, 22:01
Zitat von qwertz543221:
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
Normalerweise kritisiere ich solche Beiträge nicht so drastisch, aber das ist doch wohl ein programmierter Witz oder was? Was ist denn daran schnell, und was lang, und wieso steht das in diesem Thread? Beispiele:

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.
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#3

Re: Langzahlen

  Alt 11. Jun 2009, 22:14
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...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

Re: Langzahlen

  Alt 11. Jun 2009, 22:17
Wenn er das mit der Bei Google suchenschriftlichen Division hinbekommt und alles auf Strings umbaut, wäre von meiner Seite aus die Geschwindigkeit zweitrangig,

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.
$2B or not $2B
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#5

Re: Langzahlen

  Alt 11. Jun 2009, 22:22
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

Re: Langzahlen

  Alt 11. Jun 2009, 22:43
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:
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;
da wo intern der String nicht verändert wird, macht sich const besser
(hab es jetzt nicht bei allem gesetzt, da ich nicht weiß, ob es möglich ist)
siehe VAR CONST OUT und Co. ... warum?

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

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:
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;
also das sollte erstmal funktionieren
und über eine Multiplication sollte sich da noch was optimieren lassen.
$2B or not $2B
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#7

Re: Langzahlen

  Alt 11. Jun 2009, 22:50
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.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: qwertz543221 kleine String-Math-Lib

  Alt 11. Jun 2009, 23:12
Ich habe diesen Thraed vom Thread http://www.delphipraxis.net/internal...t.php?t=158392 abgetrennt. dae er nur bedingt etwas mit dem ursprünglichen zu tun hat.
Markus Kinzler
  Mit Zitat antworten Zitat
qwertz543221
(Gast)

n/a Beiträge
 
#9

Re: qwertz543221 kleine String-Math-Lib

  Alt 11. Jun 2009, 23:16
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?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

Re: qwertz543221 kleine String-Math-Lib

  Alt 12. Jun 2009, 11:02
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.

hier mal ein Vorschlag, für eine Basisklasse:
Delphi-Quellcode:
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.
und zur Verwendung: eine Instanz der Klasse anlegen und schon kann's losgehn
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;
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz